ActivityManagerService.java revision 5bb57e8543b0da2959a7744ed8aa957d12c635ce
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;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90
91import com.google.android.collect.Lists;
92import com.google.android.collect.Maps;
93
94import libcore.io.IoUtils;
95
96import org.xmlpull.v1.XmlPullParser;
97import org.xmlpull.v1.XmlPullParserException;
98import org.xmlpull.v1.XmlSerializer;
99
100import android.app.Activity;
101import android.app.ActivityManager;
102import android.app.ActivityManager.RunningTaskInfo;
103import android.app.ActivityManager.StackInfo;
104import android.app.ActivityManagerInternal;
105import android.app.ActivityManagerNative;
106import android.app.ActivityOptions;
107import android.app.ActivityThread;
108import android.app.AlertDialog;
109import android.app.AppGlobals;
110import android.app.ApplicationErrorReport;
111import android.app.Dialog;
112import android.app.IActivityController;
113import android.app.IApplicationThread;
114import android.app.IInstrumentationWatcher;
115import android.app.INotificationManager;
116import android.app.IProcessObserver;
117import android.app.IServiceConnection;
118import android.app.IStopUserCallback;
119import android.app.IUiAutomationConnection;
120import android.app.IUserSwitchObserver;
121import android.app.Instrumentation;
122import android.app.Notification;
123import android.app.NotificationManager;
124import android.app.PendingIntent;
125import android.app.backup.IBackupManager;
126import android.content.ActivityNotFoundException;
127import android.content.BroadcastReceiver;
128import android.content.ClipData;
129import android.content.ComponentCallbacks2;
130import android.content.ComponentName;
131import android.content.ContentProvider;
132import android.content.ContentResolver;
133import android.content.Context;
134import android.content.DialogInterface;
135import android.content.IContentProvider;
136import android.content.IIntentReceiver;
137import android.content.IIntentSender;
138import android.content.Intent;
139import android.content.IntentFilter;
140import android.content.IntentSender;
141import android.content.pm.ActivityInfo;
142import android.content.pm.ApplicationInfo;
143import android.content.pm.ConfigurationInfo;
144import android.content.pm.IPackageDataObserver;
145import android.content.pm.IPackageManager;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.PackageInfo;
148import android.content.pm.PackageManager;
149import android.content.pm.ParceledListSlice;
150import android.content.pm.UserInfo;
151import android.content.pm.PackageManager.NameNotFoundException;
152import android.content.pm.PathPermission;
153import android.content.pm.ProviderInfo;
154import android.content.pm.ResolveInfo;
155import android.content.pm.ServiceInfo;
156import android.content.res.CompatibilityInfo;
157import android.content.res.Configuration;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.Binder;
162import android.os.Build;
163import android.os.Bundle;
164import android.os.Debug;
165import android.os.DropBoxManager;
166import android.os.Environment;
167import android.os.FactoryTest;
168import android.os.FileObserver;
169import android.os.FileUtils;
170import android.os.Handler;
171import android.os.IBinder;
172import android.os.IPermissionController;
173import android.os.IProcessInfoService;
174import android.os.IRemoteCallback;
175import android.os.IUserManager;
176import android.os.Looper;
177import android.os.Message;
178import android.os.Parcel;
179import android.os.ParcelFileDescriptor;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.SELinux;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.provider.Settings;
193import android.text.format.DateUtils;
194import android.text.format.Time;
195import android.util.AtomicFile;
196import android.util.EventLog;
197import android.util.Log;
198import android.util.Pair;
199import android.util.PrintWriterPrinter;
200import android.util.Slog;
201import android.util.SparseArray;
202import android.util.TimeUtils;
203import android.util.Xml;
204import android.view.Gravity;
205import android.view.LayoutInflater;
206import android.view.View;
207import android.view.WindowManager;
208
209import dalvik.system.VMRuntime;
210
211import java.io.BufferedInputStream;
212import java.io.BufferedOutputStream;
213import java.io.DataInputStream;
214import java.io.DataOutputStream;
215import java.io.File;
216import java.io.FileDescriptor;
217import java.io.FileInputStream;
218import java.io.FileNotFoundException;
219import java.io.FileOutputStream;
220import java.io.IOException;
221import java.io.InputStreamReader;
222import java.io.PrintWriter;
223import java.io.StringWriter;
224import java.lang.ref.WeakReference;
225import java.util.ArrayList;
226import java.util.Arrays;
227import java.util.Collections;
228import java.util.Comparator;
229import java.util.HashMap;
230import java.util.HashSet;
231import java.util.Iterator;
232import java.util.List;
233import java.util.Locale;
234import java.util.Map;
235import java.util.Set;
236import java.util.concurrent.atomic.AtomicBoolean;
237import java.util.concurrent.atomic.AtomicLong;
238
239public final class ActivityManagerService extends ActivityManagerNative
240        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
241
242    private static final String USER_DATA_DIR = "/data/user/";
243    // File that stores last updated system version and called preboot receivers
244    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
245
246    static final String TAG = "ActivityManager";
247    static final String TAG_MU = "ActivityManagerServiceMU";
248    static final boolean DEBUG = false;
249    static final boolean localLOGV = DEBUG;
250    static final boolean DEBUG_BACKUP = localLOGV || false;
251    static final boolean DEBUG_BROADCAST = localLOGV || false;
252    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
253    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
254    static final boolean DEBUG_CLEANUP = localLOGV || false;
255    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
256    static final boolean DEBUG_FOCUS = false;
257    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
258    static final boolean DEBUG_MU = localLOGV || false;
259    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
260    static final boolean DEBUG_LRU = localLOGV || false;
261    static final boolean DEBUG_PAUSE = localLOGV || false;
262    static final boolean DEBUG_POWER = localLOGV || false;
263    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
264    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
265    static final boolean DEBUG_PROCESSES = localLOGV || false;
266    static final boolean DEBUG_PROVIDER = localLOGV || false;
267    static final boolean DEBUG_RESULTS = localLOGV || false;
268    static final boolean DEBUG_SERVICE = localLOGV || false;
269    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
270    static final boolean DEBUG_STACK = localLOGV || false;
271    static final boolean DEBUG_SWITCH = localLOGV || false;
272    static final boolean DEBUG_TASKS = localLOGV || false;
273    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
274    static final boolean DEBUG_TRANSITION = localLOGV || false;
275    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
276    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
277    static final boolean DEBUG_VISBILITY = localLOGV || false;
278    static final boolean DEBUG_PSS = localLOGV || false;
279    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
280    static final boolean DEBUG_RECENTS = localLOGV || false;
281    static final boolean VALIDATE_TOKENS = false;
282    static final boolean SHOW_ACTIVITY_START_TIME = true;
283
284    // Control over CPU and battery monitoring.
285    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
286    static final boolean MONITOR_CPU_USAGE = true;
287    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
288    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
289    static final boolean MONITOR_THREAD_CPU_USAGE = false;
290
291    // The flags that are set for all calls we make to the package manager.
292    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
293
294    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
295
296    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
297
298    // Amount of time after a call to stopAppSwitches() during which we will
299    // prevent further untrusted switches from happening.
300    static final long APP_SWITCH_DELAY_TIME = 5*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.
304    static final int PROC_START_TIMEOUT = 10*1000;
305
306    // How long we wait for a launched process to attach to the activity manager
307    // before we decide it's never going to come up for real, when the process was
308    // started with a wrapper for instrumentation (such as Valgrind) because it
309    // could take much longer than usual.
310    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
311
312    // How long to wait after going idle before forcing apps to GC.
313    static final int GC_TIMEOUT = 5*1000;
314
315    // The minimum amount of time between successive GC requests for a process.
316    static final int GC_MIN_INTERVAL = 60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process.
319    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process
322    // when the request is due to the memory state being lowered.
323    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
324
325    // The rate at which we check for apps using excessive power -- 15 mins.
326    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on wake locks to start killing things.
330    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on CPU usage to start killing things.
334    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // How long we allow a receiver to run before giving up on it.
337    static final int BROADCAST_FG_TIMEOUT = 10*1000;
338    static final int BROADCAST_BG_TIMEOUT = 60*1000;
339
340    // How long we wait until we timeout on key dispatching.
341    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
342
343    // How long we wait until we timeout on key dispatching during instrumentation.
344    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
345
346    // Amount of time we wait for observers to handle a user switch before
347    // giving up on them and unfreezing the screen.
348    static final int USER_SWITCH_TIMEOUT = 2*1000;
349
350    // Maximum number of users we allow to be running at a time.
351    static final int MAX_RUNNING_USERS = 3;
352
353    // How long to wait in getAssistContextExtras for the activity and foreground services
354    // to respond with the result.
355    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
356
357    // Maximum number of persisted Uri grants a package is allowed
358    static final int MAX_PERSISTED_URI_GRANTS = 128;
359
360    static final int MY_PID = Process.myPid();
361
362    static final String[] EMPTY_STRING_ARRAY = new String[0];
363
364    // How many bytes to write into the dropbox log before truncating
365    static final int DROPBOX_MAX_SIZE = 256 * 1024;
366
367    // Access modes for handleIncomingUser.
368    static final int ALLOW_NON_FULL = 0;
369    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
370    static final int ALLOW_FULL_ONLY = 2;
371
372    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
373
374    // Delay in notifying task stack change listeners (in millis)
375    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
376
377    /** All system services */
378    SystemServiceManager mSystemServiceManager;
379
380    private Installer mInstaller;
381
382    /** Run all ActivityStacks through this */
383    ActivityStackSupervisor mStackSupervisor;
384
385    /** Task stack change listeners. */
386    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
387            new RemoteCallbackList<ITaskStackListener>();
388
389    public IntentFirewall mIntentFirewall;
390
391    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
392    // default actuion automatically.  Important for devices without direct input
393    // devices.
394    private boolean mShowDialogs = true;
395
396    BroadcastQueue mFgBroadcastQueue;
397    BroadcastQueue mBgBroadcastQueue;
398    // Convenient for easy iteration over the queues. Foreground is first
399    // so that dispatch of foreground broadcasts gets precedence.
400    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
401
402    BroadcastQueue broadcastQueueForIntent(Intent intent) {
403        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
404        if (DEBUG_BACKGROUND_BROADCAST) {
405            Slog.i(TAG, "Broadcast intent " + intent + " on "
406                    + (isFg ? "foreground" : "background")
407                    + " queue");
408        }
409        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
410    }
411
412    /**
413     * Activity we have told the window manager to have key focus.
414     */
415    ActivityRecord mFocusedActivity = null;
416
417    /**
418     * List of intents that were used to start the most recent tasks.
419     */
420    private final RecentTasks mRecentTasks;
421
422    /**
423     * For addAppTask: cached of the last activity component that was added.
424     */
425    ComponentName mLastAddedTaskComponent;
426
427    /**
428     * For addAppTask: cached of the last activity uid that was added.
429     */
430    int mLastAddedTaskUid;
431
432    /**
433     * For addAppTask: cached of the last ActivityInfo that was added.
434     */
435    ActivityInfo mLastAddedTaskActivity;
436
437    public class PendingAssistExtras extends Binder implements Runnable {
438        public final ActivityRecord activity;
439        public final Bundle extras;
440        public final Intent intent;
441        public final String hint;
442        public final int userHandle;
443        public boolean haveResult = false;
444        public Bundle result = null;
445        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
446                String _hint, int _userHandle) {
447            activity = _activity;
448            extras = _extras;
449            intent = _intent;
450            hint = _hint;
451            userHandle = _userHandle;
452        }
453        @Override
454        public void run() {
455            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
456            synchronized (this) {
457                haveResult = true;
458                notifyAll();
459            }
460        }
461    }
462
463    final ArrayList<PendingAssistExtras> mPendingAssistExtras
464            = new ArrayList<PendingAssistExtras>();
465
466    /**
467     * Process management.
468     */
469    final ProcessList mProcessList = new ProcessList();
470
471    /**
472     * All of the applications we currently have running organized by name.
473     * The keys are strings of the application package name (as
474     * returned by the package manager), and the keys are ApplicationRecord
475     * objects.
476     */
477    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
478
479    /**
480     * Tracking long-term execution of processes to look for abuse and other
481     * bad app behavior.
482     */
483    final ProcessStatsService mProcessStats;
484
485    /**
486     * The currently running isolated processes.
487     */
488    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
489
490    /**
491     * Counter for assigning isolated process uids, to avoid frequently reusing the
492     * same ones.
493     */
494    int mNextIsolatedProcessUid = 0;
495
496    /**
497     * The currently running heavy-weight process, if any.
498     */
499    ProcessRecord mHeavyWeightProcess = null;
500
501    /**
502     * The last time that various processes have crashed.
503     */
504    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
505
506    /**
507     * Information about a process that is currently marked as bad.
508     */
509    static final class BadProcessInfo {
510        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
511            this.time = time;
512            this.shortMsg = shortMsg;
513            this.longMsg = longMsg;
514            this.stack = stack;
515        }
516
517        final long time;
518        final String shortMsg;
519        final String longMsg;
520        final String stack;
521    }
522
523    /**
524     * Set of applications that we consider to be bad, and will reject
525     * incoming broadcasts from (which the user has no control over).
526     * Processes are added to this set when they have crashed twice within
527     * a minimum amount of time; they are removed from it when they are
528     * later restarted (hopefully due to some user action).  The value is the
529     * time it was added to the list.
530     */
531    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
532
533    /**
534     * All of the processes we currently have running organized by pid.
535     * The keys are the pid running the application.
536     *
537     * <p>NOTE: This object is protected by its own lock, NOT the global
538     * activity manager lock!
539     */
540    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
541
542    /**
543     * All of the processes that have been forced to be foreground.  The key
544     * is the pid of the caller who requested it (we hold a death
545     * link on it).
546     */
547    abstract class ForegroundToken implements IBinder.DeathRecipient {
548        int pid;
549        IBinder token;
550    }
551    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
552
553    /**
554     * List of records for processes that someone had tried to start before the
555     * system was ready.  We don't start them at that point, but ensure they
556     * are started by the time booting is complete.
557     */
558    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
559
560    /**
561     * List of persistent applications that are in the process
562     * of being started.
563     */
564    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Processes that are being forcibly torn down.
568     */
569    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
570
571    /**
572     * List of running applications, sorted by recent usage.
573     * The first entry in the list is the least recently used.
574     */
575    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * Where in mLruProcesses that the processes hosting activities start.
579     */
580    int mLruProcessActivityStart = 0;
581
582    /**
583     * Where in mLruProcesses that the processes hosting services start.
584     * This is after (lower index) than mLruProcessesActivityStart.
585     */
586    int mLruProcessServiceStart = 0;
587
588    /**
589     * List of processes that should gc as soon as things are idle.
590     */
591    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
592
593    /**
594     * Processes we want to collect PSS data from.
595     */
596    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
597
598    /**
599     * Last time we requested PSS data of all processes.
600     */
601    long mLastFullPssTime = SystemClock.uptimeMillis();
602
603    /**
604     * If set, the next time we collect PSS data we should do a full collection
605     * with data from native processes and the kernel.
606     */
607    boolean mFullPssPending = false;
608
609    /**
610     * This is the process holding what we currently consider to be
611     * the "home" activity.
612     */
613    ProcessRecord mHomeProcess;
614
615    /**
616     * This is the process holding the activity the user last visited that
617     * is in a different process from the one they are currently in.
618     */
619    ProcessRecord mPreviousProcess;
620
621    /**
622     * The time at which the previous process was last visible.
623     */
624    long mPreviousProcessVisibleTime;
625
626    /**
627     * Which uses have been started, so are allowed to run code.
628     */
629    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
630
631    /**
632     * LRU list of history of current users.  Most recently current is at the end.
633     */
634    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
635
636    /**
637     * Constant array of the users that are currently started.
638     */
639    int[] mStartedUserArray = new int[] { 0 };
640
641    /**
642     * Registered observers of the user switching mechanics.
643     */
644    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
645            = new RemoteCallbackList<IUserSwitchObserver>();
646
647    /**
648     * Currently active user switch.
649     */
650    Object mCurUserSwitchCallback;
651
652    /**
653     * Packages that the user has asked to have run in screen size
654     * compatibility mode instead of filling the screen.
655     */
656    final CompatModePackages mCompatModePackages;
657
658    /**
659     * Set of IntentSenderRecord objects that are currently active.
660     */
661    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
662            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
663
664    /**
665     * Fingerprints (hashCode()) of stack traces that we've
666     * already logged DropBox entries for.  Guarded by itself.  If
667     * something (rogue user app) forces this over
668     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
669     */
670    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
671    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
672
673    /**
674     * Strict Mode background batched logging state.
675     *
676     * The string buffer is guarded by itself, and its lock is also
677     * used to determine if another batched write is already
678     * in-flight.
679     */
680    private final StringBuilder mStrictModeBuffer = new StringBuilder();
681
682    /**
683     * Keeps track of all IIntentReceivers that have been registered for
684     * broadcasts.  Hash keys are the receiver IBinder, hash value is
685     * a ReceiverList.
686     */
687    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
688            new HashMap<IBinder, ReceiverList>();
689
690    /**
691     * Resolver for broadcast intents to registered receivers.
692     * Holds BroadcastFilter (subclass of IntentFilter).
693     */
694    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
695            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
696        @Override
697        protected boolean allowFilterResult(
698                BroadcastFilter filter, List<BroadcastFilter> dest) {
699            IBinder target = filter.receiverList.receiver.asBinder();
700            for (int i=dest.size()-1; i>=0; i--) {
701                if (dest.get(i).receiverList.receiver.asBinder() == target) {
702                    return false;
703                }
704            }
705            return true;
706        }
707
708        @Override
709        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
710            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
711                    || userId == filter.owningUserId) {
712                return super.newResult(filter, match, userId);
713            }
714            return null;
715        }
716
717        @Override
718        protected BroadcastFilter[] newArray(int size) {
719            return new BroadcastFilter[size];
720        }
721
722        @Override
723        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
724            return packageName.equals(filter.packageName);
725        }
726    };
727
728    /**
729     * State of all active sticky broadcasts per user.  Keys are the action of the
730     * sticky Intent, values are an ArrayList of all broadcasted intents with
731     * that action (which should usually be one).  The SparseArray is keyed
732     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
733     * for stickies that are sent to all users.
734     */
735    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
736            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
737
738    final ActiveServices mServices;
739
740    final static class Association {
741        final int mSourceUid;
742        final String mSourceProcess;
743        final int mTargetUid;
744        final ComponentName mTargetComponent;
745        final String mTargetProcess;
746
747        int mCount;
748        long mTime;
749
750        int mNesting;
751        long mStartTime;
752
753        Association(int sourceUid, String sourceProcess, int targetUid,
754                ComponentName targetComponent, String targetProcess) {
755            mSourceUid = sourceUid;
756            mSourceProcess = sourceProcess;
757            mTargetUid = targetUid;
758            mTargetComponent = targetComponent;
759            mTargetProcess = targetProcess;
760        }
761    }
762
763    /**
764     * When service association tracking is enabled, this is all of the associations we
765     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
766     * -> association data.
767     */
768    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
769            mAssociations = new SparseArray<>();
770    boolean mTrackingAssociations;
771
772    /**
773     * Backup/restore process management
774     */
775    String mBackupAppName = null;
776    BackupRecord mBackupTarget = null;
777
778    final ProviderMap mProviderMap;
779
780    /**
781     * List of content providers who have clients waiting for them.  The
782     * application is currently being launched and the provider will be
783     * removed from this list once it is published.
784     */
785    final ArrayList<ContentProviderRecord> mLaunchingProviders
786            = new ArrayList<ContentProviderRecord>();
787
788    /**
789     * File storing persisted {@link #mGrantedUriPermissions}.
790     */
791    private final AtomicFile mGrantFile;
792
793    /** XML constants used in {@link #mGrantFile} */
794    private static final String TAG_URI_GRANTS = "uri-grants";
795    private static final String TAG_URI_GRANT = "uri-grant";
796    private static final String ATTR_USER_HANDLE = "userHandle";
797    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
798    private static final String ATTR_TARGET_USER_ID = "targetUserId";
799    private static final String ATTR_SOURCE_PKG = "sourcePkg";
800    private static final String ATTR_TARGET_PKG = "targetPkg";
801    private static final String ATTR_URI = "uri";
802    private static final String ATTR_MODE_FLAGS = "modeFlags";
803    private static final String ATTR_CREATED_TIME = "createdTime";
804    private static final String ATTR_PREFIX = "prefix";
805
806    /**
807     * Global set of specific {@link Uri} permissions that have been granted.
808     * This optimized lookup structure maps from {@link UriPermission#targetUid}
809     * to {@link UriPermission#uri} to {@link UriPermission}.
810     */
811    @GuardedBy("this")
812    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
813            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
814
815    public static class GrantUri {
816        public final int sourceUserId;
817        public final Uri uri;
818        public boolean prefix;
819
820        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
821            this.sourceUserId = sourceUserId;
822            this.uri = uri;
823            this.prefix = prefix;
824        }
825
826        @Override
827        public int hashCode() {
828            int hashCode = 1;
829            hashCode = 31 * hashCode + sourceUserId;
830            hashCode = 31 * hashCode + uri.hashCode();
831            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
832            return hashCode;
833        }
834
835        @Override
836        public boolean equals(Object o) {
837            if (o instanceof GrantUri) {
838                GrantUri other = (GrantUri) o;
839                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
840                        && prefix == other.prefix;
841            }
842            return false;
843        }
844
845        @Override
846        public String toString() {
847            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
848            if (prefix) result += " [prefix]";
849            return result;
850        }
851
852        public String toSafeString() {
853            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
854            if (prefix) result += " [prefix]";
855            return result;
856        }
857
858        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
859            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
860                    ContentProvider.getUriWithoutUserId(uri), false);
861        }
862    }
863
864    CoreSettingsObserver mCoreSettingsObserver;
865
866    /**
867     * Thread-local storage used to carry caller permissions over through
868     * indirect content-provider access.
869     */
870    private class Identity {
871        public final IBinder token;
872        public final int pid;
873        public final int uid;
874
875        Identity(IBinder _token, int _pid, int _uid) {
876            token = _token;
877            pid = _pid;
878            uid = _uid;
879        }
880    }
881
882    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
883
884    /**
885     * All information we have collected about the runtime performance of
886     * any user id that can impact battery performance.
887     */
888    final BatteryStatsService mBatteryStatsService;
889
890    /**
891     * Information about component usage
892     */
893    UsageStatsManagerInternal mUsageStatsService;
894
895    /**
896     * Information about and control over application operations
897     */
898    final AppOpsService mAppOpsService;
899
900    /**
901     * Save recent tasks information across reboots.
902     */
903    final TaskPersister mTaskPersister;
904
905    /**
906     * Current configuration information.  HistoryRecord objects are given
907     * a reference to this object to indicate which configuration they are
908     * currently running in, so this object must be kept immutable.
909     */
910    Configuration mConfiguration = new Configuration();
911
912    /**
913     * Current sequencing integer of the configuration, for skipping old
914     * configurations.
915     */
916    int mConfigurationSeq = 0;
917
918    /**
919     * Hardware-reported OpenGLES version.
920     */
921    final int GL_ES_VERSION;
922
923    /**
924     * List of initialization arguments to pass to all processes when binding applications to them.
925     * For example, references to the commonly used services.
926     */
927    HashMap<String, IBinder> mAppBindArgs;
928
929    /**
930     * Temporary to avoid allocations.  Protected by main lock.
931     */
932    final StringBuilder mStringBuilder = new StringBuilder(256);
933
934    /**
935     * Used to control how we initialize the service.
936     */
937    ComponentName mTopComponent;
938    String mTopAction = Intent.ACTION_MAIN;
939    String mTopData;
940    boolean mProcessesReady = false;
941    boolean mSystemReady = false;
942    boolean mBooting = false;
943    boolean mCallFinishBooting = false;
944    boolean mBootAnimationComplete = false;
945    boolean mWaitingUpdate = false;
946    boolean mDidUpdate = false;
947    boolean mOnBattery = false;
948    boolean mLaunchWarningShown = false;
949
950    Context mContext;
951
952    int mFactoryTest;
953
954    boolean mCheckedForSetup;
955
956    /**
957     * The time at which we will allow normal application switches again,
958     * after a call to {@link #stopAppSwitches()}.
959     */
960    long mAppSwitchesAllowedTime;
961
962    /**
963     * This is set to true after the first switch after mAppSwitchesAllowedTime
964     * is set; any switches after that will clear the time.
965     */
966    boolean mDidAppSwitch;
967
968    /**
969     * Last time (in realtime) at which we checked for power usage.
970     */
971    long mLastPowerCheckRealtime;
972
973    /**
974     * Last time (in uptime) at which we checked for power usage.
975     */
976    long mLastPowerCheckUptime;
977
978    /**
979     * Set while we are wanting to sleep, to prevent any
980     * activities from being started/resumed.
981     */
982    private boolean mSleeping = false;
983
984    /**
985     * Set while we are running a voice interaction.  This overrides
986     * sleeping while it is active.
987     */
988    private boolean mRunningVoice = false;
989
990    /**
991     * State of external calls telling us if the device is awake or asleep.
992     */
993    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
994
995    static final int LOCK_SCREEN_HIDDEN = 0;
996    static final int LOCK_SCREEN_LEAVING = 1;
997    static final int LOCK_SCREEN_SHOWN = 2;
998    /**
999     * State of external call telling us if the lock screen is shown.
1000     */
1001    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1002
1003    /**
1004     * Set if we are shutting down the system, similar to sleeping.
1005     */
1006    boolean mShuttingDown = false;
1007
1008    /**
1009     * Current sequence id for oom_adj computation traversal.
1010     */
1011    int mAdjSeq = 0;
1012
1013    /**
1014     * Current sequence id for process LRU updating.
1015     */
1016    int mLruSeq = 0;
1017
1018    /**
1019     * Keep track of the non-cached/empty process we last found, to help
1020     * determine how to distribute cached/empty processes next time.
1021     */
1022    int mNumNonCachedProcs = 0;
1023
1024    /**
1025     * Keep track of the number of cached hidden procs, to balance oom adj
1026     * distribution between those and empty procs.
1027     */
1028    int mNumCachedHiddenProcs = 0;
1029
1030    /**
1031     * Keep track of the number of service processes we last found, to
1032     * determine on the next iteration which should be B services.
1033     */
1034    int mNumServiceProcs = 0;
1035    int mNewNumAServiceProcs = 0;
1036    int mNewNumServiceProcs = 0;
1037
1038    /**
1039     * Allow the current computed overall memory level of the system to go down?
1040     * This is set to false when we are killing processes for reasons other than
1041     * memory management, so that the now smaller process list will not be taken as
1042     * an indication that memory is tighter.
1043     */
1044    boolean mAllowLowerMemLevel = false;
1045
1046    /**
1047     * The last computed memory level, for holding when we are in a state that
1048     * processes are going away for other reasons.
1049     */
1050    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1051
1052    /**
1053     * The last total number of process we have, to determine if changes actually look
1054     * like a shrinking number of process due to lower RAM.
1055     */
1056    int mLastNumProcesses;
1057
1058    /**
1059     * The uptime of the last time we performed idle maintenance.
1060     */
1061    long mLastIdleTime = SystemClock.uptimeMillis();
1062
1063    /**
1064     * Total time spent with RAM that has been added in the past since the last idle time.
1065     */
1066    long mLowRamTimeSinceLastIdle = 0;
1067
1068    /**
1069     * If RAM is currently low, when that horrible situation started.
1070     */
1071    long mLowRamStartTime = 0;
1072
1073    /**
1074     * For reporting to battery stats the current top application.
1075     */
1076    private String mCurResumedPackage = null;
1077    private int mCurResumedUid = -1;
1078
1079    /**
1080     * For reporting to battery stats the apps currently running foreground
1081     * service.  The ProcessMap is package/uid tuples; each of these contain
1082     * an array of the currently foreground processes.
1083     */
1084    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1085            = new ProcessMap<ArrayList<ProcessRecord>>();
1086
1087    /**
1088     * This is set if we had to do a delayed dexopt of an app before launching
1089     * it, to increase the ANR timeouts in that case.
1090     */
1091    boolean mDidDexOpt;
1092
1093    /**
1094     * Set if the systemServer made a call to enterSafeMode.
1095     */
1096    boolean mSafeMode;
1097
1098    /**
1099     * If true, we are running under a test environment so will sample PSS from processes
1100     * much more rapidly to try to collect better data when the tests are rapidly
1101     * running through apps.
1102     */
1103    boolean mTestPssMode = false;
1104
1105    String mDebugApp = null;
1106    boolean mWaitForDebugger = false;
1107    boolean mDebugTransient = false;
1108    String mOrigDebugApp = null;
1109    boolean mOrigWaitForDebugger = false;
1110    boolean mAlwaysFinishActivities = false;
1111    IActivityController mController = null;
1112    String mProfileApp = null;
1113    ProcessRecord mProfileProc = null;
1114    String mProfileFile;
1115    ParcelFileDescriptor mProfileFd;
1116    int mSamplingInterval = 0;
1117    boolean mAutoStopProfiler = false;
1118    int mProfileType = 0;
1119    String mOpenGlTraceApp = null;
1120
1121    final long[] mTmpLong = new long[1];
1122
1123    static class ProcessChangeItem {
1124        static final int CHANGE_ACTIVITIES = 1<<0;
1125        static final int CHANGE_PROCESS_STATE = 1<<1;
1126        int changes;
1127        int uid;
1128        int pid;
1129        int processState;
1130        boolean foregroundActivities;
1131    }
1132
1133    final RemoteCallbackList<IProcessObserver> mProcessObservers
1134            = new RemoteCallbackList<IProcessObserver>();
1135    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1136
1137    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1138            = new ArrayList<ProcessChangeItem>();
1139    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1140            = new ArrayList<ProcessChangeItem>();
1141
1142    /**
1143     * Runtime CPU use collection thread.  This object's lock is used to
1144     * perform synchronization with the thread (notifying it to run).
1145     */
1146    final Thread mProcessCpuThread;
1147
1148    /**
1149     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1150     * Must acquire this object's lock when accessing it.
1151     * NOTE: this lock will be held while doing long operations (trawling
1152     * through all processes in /proc), so it should never be acquired by
1153     * any critical paths such as when holding the main activity manager lock.
1154     */
1155    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1156            MONITOR_THREAD_CPU_USAGE);
1157    final AtomicLong mLastCpuTime = new AtomicLong(0);
1158    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1159
1160    long mLastWriteTime = 0;
1161
1162    /**
1163     * Used to retain an update lock when the foreground activity is in
1164     * immersive mode.
1165     */
1166    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1167
1168    /**
1169     * Set to true after the system has finished booting.
1170     */
1171    boolean mBooted = false;
1172
1173    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1174    int mProcessLimitOverride = -1;
1175
1176    WindowManagerService mWindowManager;
1177
1178    final ActivityThread mSystemThread;
1179
1180    // Holds the current foreground user's id
1181    int mCurrentUserId = 0;
1182    // Holds the target user's id during a user switch
1183    int mTargetUserId = UserHandle.USER_NULL;
1184    // If there are multiple profiles for the current user, their ids are here
1185    // Currently only the primary user can have managed profiles
1186    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1187
1188    /**
1189     * Mapping from each known user ID to the profile group ID it is associated with.
1190     */
1191    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1192
1193    private UserManagerService mUserManager;
1194
1195    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1196        final ProcessRecord mApp;
1197        final int mPid;
1198        final IApplicationThread mAppThread;
1199
1200        AppDeathRecipient(ProcessRecord app, int pid,
1201                IApplicationThread thread) {
1202            if (localLOGV) Slog.v(
1203                TAG, "New death recipient " + this
1204                + " for thread " + thread.asBinder());
1205            mApp = app;
1206            mPid = pid;
1207            mAppThread = thread;
1208        }
1209
1210        @Override
1211        public void binderDied() {
1212            if (localLOGV) Slog.v(
1213                TAG, "Death received in " + this
1214                + " for thread " + mAppThread.asBinder());
1215            synchronized(ActivityManagerService.this) {
1216                appDiedLocked(mApp, mPid, mAppThread);
1217            }
1218        }
1219    }
1220
1221    static final int SHOW_ERROR_MSG = 1;
1222    static final int SHOW_NOT_RESPONDING_MSG = 2;
1223    static final int SHOW_FACTORY_ERROR_MSG = 3;
1224    static final int UPDATE_CONFIGURATION_MSG = 4;
1225    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1226    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1227    static final int SERVICE_TIMEOUT_MSG = 12;
1228    static final int UPDATE_TIME_ZONE = 13;
1229    static final int SHOW_UID_ERROR_MSG = 14;
1230    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1231    static final int PROC_START_TIMEOUT_MSG = 20;
1232    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1233    static final int KILL_APPLICATION_MSG = 22;
1234    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1235    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1236    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1237    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1238    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1239    static final int CLEAR_DNS_CACHE_MSG = 28;
1240    static final int UPDATE_HTTP_PROXY_MSG = 29;
1241    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1242    static final int DISPATCH_PROCESSES_CHANGED = 31;
1243    static final int DISPATCH_PROCESS_DIED = 32;
1244    static final int REPORT_MEM_USAGE_MSG = 33;
1245    static final int REPORT_USER_SWITCH_MSG = 34;
1246    static final int CONTINUE_USER_SWITCH_MSG = 35;
1247    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1248    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1249    static final int PERSIST_URI_GRANTS_MSG = 38;
1250    static final int REQUEST_ALL_PSS_MSG = 39;
1251    static final int START_PROFILES_MSG = 40;
1252    static final int UPDATE_TIME = 41;
1253    static final int SYSTEM_USER_START_MSG = 42;
1254    static final int SYSTEM_USER_CURRENT_MSG = 43;
1255    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1256    static final int FINISH_BOOTING_MSG = 45;
1257    static final int START_USER_SWITCH_MSG = 46;
1258    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1259    static final int DISMISS_DIALOG_MSG = 48;
1260    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1261    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1262
1263    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1264    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1265    static final int FIRST_COMPAT_MODE_MSG = 300;
1266    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1267
1268    CompatModeDialog mCompatModeDialog;
1269    long mLastMemUsageReportTime = 0;
1270
1271    /**
1272     * Flag whether the current user is a "monkey", i.e. whether
1273     * the UI is driven by a UI automation tool.
1274     */
1275    private boolean mUserIsMonkey;
1276
1277    /** Flag whether the device has a Recents UI */
1278    boolean mHasRecents;
1279
1280    /** The dimensions of the thumbnails in the Recents UI. */
1281    int mThumbnailWidth;
1282    int mThumbnailHeight;
1283
1284    final ServiceThread mHandlerThread;
1285    final MainHandler mHandler;
1286
1287    final class MainHandler extends Handler {
1288        public MainHandler(Looper looper) {
1289            super(looper, null, true);
1290        }
1291
1292        @Override
1293        public void handleMessage(Message msg) {
1294            switch (msg.what) {
1295            case SHOW_ERROR_MSG: {
1296                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1297                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1298                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1299                synchronized (ActivityManagerService.this) {
1300                    ProcessRecord proc = (ProcessRecord)data.get("app");
1301                    AppErrorResult res = (AppErrorResult) data.get("result");
1302                    if (proc != null && proc.crashDialog != null) {
1303                        Slog.e(TAG, "App already has crash dialog: " + proc);
1304                        if (res != null) {
1305                            res.set(0);
1306                        }
1307                        return;
1308                    }
1309                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1310                            >= Process.FIRST_APPLICATION_UID
1311                            && proc.pid != MY_PID);
1312                    for (int userId : mCurrentProfileIds) {
1313                        isBackground &= (proc.userId != userId);
1314                    }
1315                    if (isBackground && !showBackground) {
1316                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1317                        if (res != null) {
1318                            res.set(0);
1319                        }
1320                        return;
1321                    }
1322                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1323                        Dialog d = new AppErrorDialog(mContext,
1324                                ActivityManagerService.this, res, proc);
1325                        d.show();
1326                        proc.crashDialog = d;
1327                    } else {
1328                        // The device is asleep, so just pretend that the user
1329                        // saw a crash dialog and hit "force quit".
1330                        if (res != null) {
1331                            res.set(0);
1332                        }
1333                    }
1334                }
1335
1336                ensureBootCompleted();
1337            } break;
1338            case SHOW_NOT_RESPONDING_MSG: {
1339                synchronized (ActivityManagerService.this) {
1340                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1341                    ProcessRecord proc = (ProcessRecord)data.get("app");
1342                    if (proc != null && proc.anrDialog != null) {
1343                        Slog.e(TAG, "App already has anr dialog: " + proc);
1344                        return;
1345                    }
1346
1347                    Intent intent = new Intent("android.intent.action.ANR");
1348                    if (!mProcessesReady) {
1349                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1350                                | Intent.FLAG_RECEIVER_FOREGROUND);
1351                    }
1352                    broadcastIntentLocked(null, null, intent,
1353                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1354                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1355
1356                    if (mShowDialogs) {
1357                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1358                                mContext, proc, (ActivityRecord)data.get("activity"),
1359                                msg.arg1 != 0);
1360                        d.show();
1361                        proc.anrDialog = d;
1362                    } else {
1363                        // Just kill the app if there is no dialog to be shown.
1364                        killAppAtUsersRequest(proc, null);
1365                    }
1366                }
1367
1368                ensureBootCompleted();
1369            } break;
1370            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1371                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1372                synchronized (ActivityManagerService.this) {
1373                    ProcessRecord proc = (ProcessRecord) data.get("app");
1374                    if (proc == null) {
1375                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1376                        break;
1377                    }
1378                    if (proc.crashDialog != null) {
1379                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1380                        return;
1381                    }
1382                    AppErrorResult res = (AppErrorResult) data.get("result");
1383                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1384                        Dialog d = new StrictModeViolationDialog(mContext,
1385                                ActivityManagerService.this, res, proc);
1386                        d.show();
1387                        proc.crashDialog = d;
1388                    } else {
1389                        // The device is asleep, so just pretend that the user
1390                        // saw a crash dialog and hit "force quit".
1391                        res.set(0);
1392                    }
1393                }
1394                ensureBootCompleted();
1395            } break;
1396            case SHOW_FACTORY_ERROR_MSG: {
1397                Dialog d = new FactoryErrorDialog(
1398                    mContext, msg.getData().getCharSequence("msg"));
1399                d.show();
1400                ensureBootCompleted();
1401            } break;
1402            case UPDATE_CONFIGURATION_MSG: {
1403                final ContentResolver resolver = mContext.getContentResolver();
1404                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1405            } break;
1406            case GC_BACKGROUND_PROCESSES_MSG: {
1407                synchronized (ActivityManagerService.this) {
1408                    performAppGcsIfAppropriateLocked();
1409                }
1410            } break;
1411            case WAIT_FOR_DEBUGGER_MSG: {
1412                synchronized (ActivityManagerService.this) {
1413                    ProcessRecord app = (ProcessRecord)msg.obj;
1414                    if (msg.arg1 != 0) {
1415                        if (!app.waitedForDebugger) {
1416                            Dialog d = new AppWaitingForDebuggerDialog(
1417                                    ActivityManagerService.this,
1418                                    mContext, app);
1419                            app.waitDialog = d;
1420                            app.waitedForDebugger = true;
1421                            d.show();
1422                        }
1423                    } else {
1424                        if (app.waitDialog != null) {
1425                            app.waitDialog.dismiss();
1426                            app.waitDialog = null;
1427                        }
1428                    }
1429                }
1430            } break;
1431            case SERVICE_TIMEOUT_MSG: {
1432                if (mDidDexOpt) {
1433                    mDidDexOpt = false;
1434                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1435                    nmsg.obj = msg.obj;
1436                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1437                    return;
1438                }
1439                mServices.serviceTimeout((ProcessRecord)msg.obj);
1440            } break;
1441            case UPDATE_TIME_ZONE: {
1442                synchronized (ActivityManagerService.this) {
1443                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1444                        ProcessRecord r = mLruProcesses.get(i);
1445                        if (r.thread != null) {
1446                            try {
1447                                r.thread.updateTimeZone();
1448                            } catch (RemoteException ex) {
1449                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1450                            }
1451                        }
1452                    }
1453                }
1454            } break;
1455            case CLEAR_DNS_CACHE_MSG: {
1456                synchronized (ActivityManagerService.this) {
1457                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1458                        ProcessRecord r = mLruProcesses.get(i);
1459                        if (r.thread != null) {
1460                            try {
1461                                r.thread.clearDnsCache();
1462                            } catch (RemoteException ex) {
1463                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1464                            }
1465                        }
1466                    }
1467                }
1468            } break;
1469            case UPDATE_HTTP_PROXY_MSG: {
1470                ProxyInfo proxy = (ProxyInfo)msg.obj;
1471                String host = "";
1472                String port = "";
1473                String exclList = "";
1474                Uri pacFileUrl = Uri.EMPTY;
1475                if (proxy != null) {
1476                    host = proxy.getHost();
1477                    port = Integer.toString(proxy.getPort());
1478                    exclList = proxy.getExclusionListAsString();
1479                    pacFileUrl = proxy.getPacFileUrl();
1480                }
1481                synchronized (ActivityManagerService.this) {
1482                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1483                        ProcessRecord r = mLruProcesses.get(i);
1484                        if (r.thread != null) {
1485                            try {
1486                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1487                            } catch (RemoteException ex) {
1488                                Slog.w(TAG, "Failed to update http proxy for: " +
1489                                        r.info.processName);
1490                            }
1491                        }
1492                    }
1493                }
1494            } break;
1495            case SHOW_UID_ERROR_MSG: {
1496                if (mShowDialogs) {
1497                    AlertDialog d = new BaseErrorDialog(mContext);
1498                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1499                    d.setCancelable(false);
1500                    d.setTitle(mContext.getText(R.string.android_system_label));
1501                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1502                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1503                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1504                    d.show();
1505                }
1506            } break;
1507            case SHOW_FINGERPRINT_ERROR_MSG: {
1508                if (mShowDialogs) {
1509                    AlertDialog d = new BaseErrorDialog(mContext);
1510                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1511                    d.setCancelable(false);
1512                    d.setTitle(mContext.getText(R.string.android_system_label));
1513                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1514                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1515                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1516                    d.show();
1517                }
1518            } break;
1519            case PROC_START_TIMEOUT_MSG: {
1520                if (mDidDexOpt) {
1521                    mDidDexOpt = false;
1522                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1523                    nmsg.obj = msg.obj;
1524                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1525                    return;
1526                }
1527                ProcessRecord app = (ProcessRecord)msg.obj;
1528                synchronized (ActivityManagerService.this) {
1529                    processStartTimedOutLocked(app);
1530                }
1531            } break;
1532            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1533                synchronized (ActivityManagerService.this) {
1534                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1535                }
1536            } break;
1537            case KILL_APPLICATION_MSG: {
1538                synchronized (ActivityManagerService.this) {
1539                    int appid = msg.arg1;
1540                    boolean restart = (msg.arg2 == 1);
1541                    Bundle bundle = (Bundle)msg.obj;
1542                    String pkg = bundle.getString("pkg");
1543                    String reason = bundle.getString("reason");
1544                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1545                            false, UserHandle.USER_ALL, reason);
1546                }
1547            } break;
1548            case FINALIZE_PENDING_INTENT_MSG: {
1549                ((PendingIntentRecord)msg.obj).completeFinalize();
1550            } break;
1551            case POST_HEAVY_NOTIFICATION_MSG: {
1552                INotificationManager inm = NotificationManager.getService();
1553                if (inm == null) {
1554                    return;
1555                }
1556
1557                ActivityRecord root = (ActivityRecord)msg.obj;
1558                ProcessRecord process = root.app;
1559                if (process == null) {
1560                    return;
1561                }
1562
1563                try {
1564                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1565                    String text = mContext.getString(R.string.heavy_weight_notification,
1566                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1567                    Notification notification = new Notification();
1568                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1569                    notification.when = 0;
1570                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1571                    notification.tickerText = text;
1572                    notification.defaults = 0; // please be quiet
1573                    notification.sound = null;
1574                    notification.vibrate = null;
1575                    notification.color = mContext.getResources().getColor(
1576                            com.android.internal.R.color.system_notification_accent_color);
1577                    notification.setLatestEventInfo(context, text,
1578                            mContext.getText(R.string.heavy_weight_notification_detail),
1579                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1580                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1581                                    new UserHandle(root.userId)));
1582
1583                    try {
1584                        int[] outId = new int[1];
1585                        inm.enqueueNotificationWithTag("android", "android", null,
1586                                R.string.heavy_weight_notification,
1587                                notification, outId, root.userId);
1588                    } catch (RuntimeException e) {
1589                        Slog.w(ActivityManagerService.TAG,
1590                                "Error showing notification for heavy-weight app", e);
1591                    } catch (RemoteException e) {
1592                    }
1593                } catch (NameNotFoundException e) {
1594                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1595                }
1596            } break;
1597            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1598                INotificationManager inm = NotificationManager.getService();
1599                if (inm == null) {
1600                    return;
1601                }
1602                try {
1603                    inm.cancelNotificationWithTag("android", null,
1604                            R.string.heavy_weight_notification,  msg.arg1);
1605                } catch (RuntimeException e) {
1606                    Slog.w(ActivityManagerService.TAG,
1607                            "Error canceling notification for service", e);
1608                } catch (RemoteException e) {
1609                }
1610            } break;
1611            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1612                synchronized (ActivityManagerService.this) {
1613                    checkExcessivePowerUsageLocked(true);
1614                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1615                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1616                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1617                }
1618            } break;
1619            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1620                synchronized (ActivityManagerService.this) {
1621                    ActivityRecord ar = (ActivityRecord)msg.obj;
1622                    if (mCompatModeDialog != null) {
1623                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1624                                ar.info.applicationInfo.packageName)) {
1625                            return;
1626                        }
1627                        mCompatModeDialog.dismiss();
1628                        mCompatModeDialog = null;
1629                    }
1630                    if (ar != null && false) {
1631                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1632                                ar.packageName)) {
1633                            int mode = mCompatModePackages.computeCompatModeLocked(
1634                                    ar.info.applicationInfo);
1635                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1636                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1637                                mCompatModeDialog = new CompatModeDialog(
1638                                        ActivityManagerService.this, mContext,
1639                                        ar.info.applicationInfo);
1640                                mCompatModeDialog.show();
1641                            }
1642                        }
1643                    }
1644                }
1645                break;
1646            }
1647            case DISPATCH_PROCESSES_CHANGED: {
1648                dispatchProcessesChanged();
1649                break;
1650            }
1651            case DISPATCH_PROCESS_DIED: {
1652                final int pid = msg.arg1;
1653                final int uid = msg.arg2;
1654                dispatchProcessDied(pid, uid);
1655                break;
1656            }
1657            case REPORT_MEM_USAGE_MSG: {
1658                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1659                Thread thread = new Thread() {
1660                    @Override public void run() {
1661                        reportMemUsage(memInfos);
1662                    }
1663                };
1664                thread.start();
1665                break;
1666            }
1667            case START_USER_SWITCH_MSG: {
1668                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1669                break;
1670            }
1671            case REPORT_USER_SWITCH_MSG: {
1672                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1673                break;
1674            }
1675            case CONTINUE_USER_SWITCH_MSG: {
1676                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1677                break;
1678            }
1679            case USER_SWITCH_TIMEOUT_MSG: {
1680                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1681                break;
1682            }
1683            case IMMERSIVE_MODE_LOCK_MSG: {
1684                final boolean nextState = (msg.arg1 != 0);
1685                if (mUpdateLock.isHeld() != nextState) {
1686                    if (DEBUG_IMMERSIVE) {
1687                        final ActivityRecord r = (ActivityRecord) msg.obj;
1688                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1689                    }
1690                    if (nextState) {
1691                        mUpdateLock.acquire();
1692                    } else {
1693                        mUpdateLock.release();
1694                    }
1695                }
1696                break;
1697            }
1698            case PERSIST_URI_GRANTS_MSG: {
1699                writeGrantedUriPermissions();
1700                break;
1701            }
1702            case REQUEST_ALL_PSS_MSG: {
1703                synchronized (ActivityManagerService.this) {
1704                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1705                }
1706                break;
1707            }
1708            case START_PROFILES_MSG: {
1709                synchronized (ActivityManagerService.this) {
1710                    startProfilesLocked();
1711                }
1712                break;
1713            }
1714            case UPDATE_TIME: {
1715                synchronized (ActivityManagerService.this) {
1716                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1717                        ProcessRecord r = mLruProcesses.get(i);
1718                        if (r.thread != null) {
1719                            try {
1720                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1721                            } catch (RemoteException ex) {
1722                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1723                            }
1724                        }
1725                    }
1726                }
1727                break;
1728            }
1729            case SYSTEM_USER_START_MSG: {
1730                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1731                        Integer.toString(msg.arg1), msg.arg1);
1732                mSystemServiceManager.startUser(msg.arg1);
1733                break;
1734            }
1735            case SYSTEM_USER_CURRENT_MSG: {
1736                mBatteryStatsService.noteEvent(
1737                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1738                        Integer.toString(msg.arg2), msg.arg2);
1739                mBatteryStatsService.noteEvent(
1740                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1741                        Integer.toString(msg.arg1), msg.arg1);
1742                mSystemServiceManager.switchUser(msg.arg1);
1743                break;
1744            }
1745            case ENTER_ANIMATION_COMPLETE_MSG: {
1746                synchronized (ActivityManagerService.this) {
1747                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1748                    if (r != null && r.app != null && r.app.thread != null) {
1749                        try {
1750                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1751                        } catch (RemoteException e) {
1752                        }
1753                    }
1754                }
1755                break;
1756            }
1757            case FINISH_BOOTING_MSG: {
1758                if (msg.arg1 != 0) {
1759                    finishBooting();
1760                }
1761                if (msg.arg2 != 0) {
1762                    enableScreenAfterBoot();
1763                }
1764                break;
1765            }
1766            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1767                try {
1768                    Locale l = (Locale) msg.obj;
1769                    IBinder service = ServiceManager.getService("mount");
1770                    IMountService mountService = IMountService.Stub.asInterface(service);
1771                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1772                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1773                } catch (RemoteException e) {
1774                    Log.e(TAG, "Error storing locale for decryption UI", e);
1775                }
1776                break;
1777            }
1778            case DISMISS_DIALOG_MSG: {
1779                final Dialog d = (Dialog) msg.obj;
1780                d.dismiss();
1781                break;
1782            }
1783            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1784                synchronized (ActivityManagerService.this) {
1785                    int i = mTaskStackListeners.beginBroadcast();
1786                    while (i > 0) {
1787                        i--;
1788                        try {
1789                            // Make a one-way callback to the listener
1790                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1791                        } catch (RemoteException e){
1792                            // Handled by the RemoteCallbackList
1793                        }
1794                    }
1795                    mTaskStackListeners.finishBroadcast();
1796                }
1797                break;
1798            }
1799            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1800                final int uid = msg.arg1;
1801                final byte[] firstPacket = (byte[]) msg.obj;
1802
1803                synchronized (mPidsSelfLocked) {
1804                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1805                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1806                        if (p.uid == uid) {
1807                            try {
1808                                p.thread.notifyCleartextNetwork(firstPacket);
1809                            } catch (RemoteException ignored) {
1810                            }
1811                        }
1812                    }
1813                }
1814                break;
1815            }
1816            }
1817        }
1818    };
1819
1820    static final int COLLECT_PSS_BG_MSG = 1;
1821
1822    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1823        @Override
1824        public void handleMessage(Message msg) {
1825            switch (msg.what) {
1826            case COLLECT_PSS_BG_MSG: {
1827                long start = SystemClock.uptimeMillis();
1828                MemInfoReader memInfo = null;
1829                synchronized (ActivityManagerService.this) {
1830                    if (mFullPssPending) {
1831                        mFullPssPending = false;
1832                        memInfo = new MemInfoReader();
1833                    }
1834                }
1835                if (memInfo != null) {
1836                    updateCpuStatsNow();
1837                    long nativeTotalPss = 0;
1838                    synchronized (mProcessCpuTracker) {
1839                        final int N = mProcessCpuTracker.countStats();
1840                        for (int j=0; j<N; j++) {
1841                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1842                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1843                                // This is definitely an application process; skip it.
1844                                continue;
1845                            }
1846                            synchronized (mPidsSelfLocked) {
1847                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1848                                    // This is one of our own processes; skip it.
1849                                    continue;
1850                                }
1851                            }
1852                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1853                        }
1854                    }
1855                    memInfo.readMemInfo();
1856                    synchronized (ActivityManagerService.this) {
1857                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1858                                + (SystemClock.uptimeMillis()-start) + "ms");
1859                        final long cachedKb = memInfo.getCachedSizeKb();
1860                        final long freeKb = memInfo.getFreeSizeKb();
1861                        final long zramKb = memInfo.getZramTotalSizeKb();
1862                        final long kernelKb = memInfo.getKernelUsedSizeKb();
1863                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
1864                                kernelKb*1024, nativeTotalPss*1024);
1865                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
1866                                nativeTotalPss);
1867                    }
1868                }
1869
1870                int num = 0;
1871                long[] tmp = new long[1];
1872                do {
1873                    ProcessRecord proc;
1874                    int procState;
1875                    int pid;
1876                    long lastPssTime;
1877                    synchronized (ActivityManagerService.this) {
1878                        if (mPendingPssProcesses.size() <= 0) {
1879                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1880                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1881                            mPendingPssProcesses.clear();
1882                            return;
1883                        }
1884                        proc = mPendingPssProcesses.remove(0);
1885                        procState = proc.pssProcState;
1886                        lastPssTime = proc.lastPssTime;
1887                        if (proc.thread != null && procState == proc.setProcState
1888                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1889                                        < SystemClock.uptimeMillis()) {
1890                            pid = proc.pid;
1891                        } else {
1892                            proc = null;
1893                            pid = 0;
1894                        }
1895                    }
1896                    if (proc != null) {
1897                        long pss = Debug.getPss(pid, tmp, null);
1898                        synchronized (ActivityManagerService.this) {
1899                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1900                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1901                                num++;
1902                                recordPssSample(proc, procState, pss, tmp[0],
1903                                        SystemClock.uptimeMillis());
1904                            }
1905                        }
1906                    }
1907                } while (true);
1908            }
1909            }
1910        }
1911    };
1912
1913    public void setSystemProcess() {
1914        try {
1915            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1916            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1917            ServiceManager.addService("meminfo", new MemBinder(this));
1918            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1919            ServiceManager.addService("dbinfo", new DbBinder(this));
1920            if (MONITOR_CPU_USAGE) {
1921                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1922            }
1923            ServiceManager.addService("permission", new PermissionController(this));
1924            ServiceManager.addService("processinfo", new ProcessInfoService(this));
1925
1926            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1927                    "android", STOCK_PM_FLAGS);
1928            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1929
1930            synchronized (this) {
1931                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1932                app.persistent = true;
1933                app.pid = MY_PID;
1934                app.maxAdj = ProcessList.SYSTEM_ADJ;
1935                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1936                mProcessNames.put(app.processName, app.uid, app);
1937                synchronized (mPidsSelfLocked) {
1938                    mPidsSelfLocked.put(app.pid, app);
1939                }
1940                updateLruProcessLocked(app, false, null);
1941                updateOomAdjLocked();
1942            }
1943        } catch (PackageManager.NameNotFoundException e) {
1944            throw new RuntimeException(
1945                    "Unable to find android system package", e);
1946        }
1947    }
1948
1949    public void setWindowManager(WindowManagerService wm) {
1950        mWindowManager = wm;
1951        mStackSupervisor.setWindowManager(wm);
1952    }
1953
1954    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1955        mUsageStatsService = usageStatsManager;
1956    }
1957
1958    public void startObservingNativeCrashes() {
1959        final NativeCrashListener ncl = new NativeCrashListener(this);
1960        ncl.start();
1961    }
1962
1963    public IAppOpsService getAppOpsService() {
1964        return mAppOpsService;
1965    }
1966
1967    static class MemBinder extends Binder {
1968        ActivityManagerService mActivityManagerService;
1969        MemBinder(ActivityManagerService activityManagerService) {
1970            mActivityManagerService = activityManagerService;
1971        }
1972
1973        @Override
1974        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1975            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1976                    != PackageManager.PERMISSION_GRANTED) {
1977                pw.println("Permission Denial: can't dump meminfo from from pid="
1978                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1979                        + " without permission " + android.Manifest.permission.DUMP);
1980                return;
1981            }
1982
1983            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1984        }
1985    }
1986
1987    static class GraphicsBinder extends Binder {
1988        ActivityManagerService mActivityManagerService;
1989        GraphicsBinder(ActivityManagerService activityManagerService) {
1990            mActivityManagerService = activityManagerService;
1991        }
1992
1993        @Override
1994        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1995            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1996                    != PackageManager.PERMISSION_GRANTED) {
1997                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1998                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1999                        + " without permission " + android.Manifest.permission.DUMP);
2000                return;
2001            }
2002
2003            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2004        }
2005    }
2006
2007    static class DbBinder extends Binder {
2008        ActivityManagerService mActivityManagerService;
2009        DbBinder(ActivityManagerService activityManagerService) {
2010            mActivityManagerService = activityManagerService;
2011        }
2012
2013        @Override
2014        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2015            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2016                    != PackageManager.PERMISSION_GRANTED) {
2017                pw.println("Permission Denial: can't dump dbinfo from from pid="
2018                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2019                        + " without permission " + android.Manifest.permission.DUMP);
2020                return;
2021            }
2022
2023            mActivityManagerService.dumpDbInfo(fd, pw, args);
2024        }
2025    }
2026
2027    static class CpuBinder extends Binder {
2028        ActivityManagerService mActivityManagerService;
2029        CpuBinder(ActivityManagerService activityManagerService) {
2030            mActivityManagerService = activityManagerService;
2031        }
2032
2033        @Override
2034        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2035            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2036                    != PackageManager.PERMISSION_GRANTED) {
2037                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2038                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2039                        + " without permission " + android.Manifest.permission.DUMP);
2040                return;
2041            }
2042
2043            synchronized (mActivityManagerService.mProcessCpuTracker) {
2044                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2045                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2046                        SystemClock.uptimeMillis()));
2047            }
2048        }
2049    }
2050
2051    public static final class Lifecycle extends SystemService {
2052        private final ActivityManagerService mService;
2053
2054        public Lifecycle(Context context) {
2055            super(context);
2056            mService = new ActivityManagerService(context);
2057        }
2058
2059        @Override
2060        public void onStart() {
2061            mService.start();
2062        }
2063
2064        public ActivityManagerService getService() {
2065            return mService;
2066        }
2067    }
2068
2069    // Note: This method is invoked on the main thread but may need to attach various
2070    // handlers to other threads.  So take care to be explicit about the looper.
2071    public ActivityManagerService(Context systemContext) {
2072        mContext = systemContext;
2073        mFactoryTest = FactoryTest.getMode();
2074        mSystemThread = ActivityThread.currentActivityThread();
2075
2076        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2077
2078        mHandlerThread = new ServiceThread(TAG,
2079                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2080        mHandlerThread.start();
2081        mHandler = new MainHandler(mHandlerThread.getLooper());
2082
2083        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2084                "foreground", BROADCAST_FG_TIMEOUT, false);
2085        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2086                "background", BROADCAST_BG_TIMEOUT, true);
2087        mBroadcastQueues[0] = mFgBroadcastQueue;
2088        mBroadcastQueues[1] = mBgBroadcastQueue;
2089
2090        mServices = new ActiveServices(this);
2091        mProviderMap = new ProviderMap(this);
2092
2093        // TODO: Move creation of battery stats service outside of activity manager service.
2094        File dataDir = Environment.getDataDirectory();
2095        File systemDir = new File(dataDir, "system");
2096        systemDir.mkdirs();
2097        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2098        mBatteryStatsService.getActiveStatistics().readLocked();
2099        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2100        mOnBattery = DEBUG_POWER ? true
2101                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2102        mBatteryStatsService.getActiveStatistics().setCallback(this);
2103
2104        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2105
2106        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2107
2108        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2109
2110        // User 0 is the first and only user that runs at boot.
2111        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2112        mUserLru.add(Integer.valueOf(0));
2113        updateStartedUserArrayLocked();
2114
2115        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2116            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2117
2118        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2119
2120        mConfiguration.setToDefaults();
2121        mConfiguration.locale = Locale.getDefault();
2122
2123        mConfigurationSeq = mConfiguration.seq = 1;
2124        mProcessCpuTracker.init();
2125
2126        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2127        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2128        mRecentTasks = new RecentTasks(this);
2129        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2130        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
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        Watchdog.getInstance().addMonitor(this);
2163        Watchdog.getInstance().addThread(mHandler);
2164    }
2165
2166    public void setSystemServiceManager(SystemServiceManager mgr) {
2167        mSystemServiceManager = mgr;
2168    }
2169
2170    public void setInstaller(Installer installer) {
2171        mInstaller = installer;
2172    }
2173
2174    private void start() {
2175        Process.removeAllProcessGroups();
2176        mProcessCpuThread.start();
2177
2178        mBatteryStatsService.publish(mContext);
2179        mAppOpsService.publish(mContext);
2180        Slog.d("AppOps", "AppOpsService published");
2181        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2182    }
2183
2184    public void initPowerManagement() {
2185        mStackSupervisor.initPowerManagement();
2186        mBatteryStatsService.initPowerManagement();
2187    }
2188
2189    @Override
2190    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2191            throws RemoteException {
2192        if (code == SYSPROPS_TRANSACTION) {
2193            // We need to tell all apps about the system property change.
2194            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2195            synchronized(this) {
2196                final int NP = mProcessNames.getMap().size();
2197                for (int ip=0; ip<NP; ip++) {
2198                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2199                    final int NA = apps.size();
2200                    for (int ia=0; ia<NA; ia++) {
2201                        ProcessRecord app = apps.valueAt(ia);
2202                        if (app.thread != null) {
2203                            procs.add(app.thread.asBinder());
2204                        }
2205                    }
2206                }
2207            }
2208
2209            int N = procs.size();
2210            for (int i=0; i<N; i++) {
2211                Parcel data2 = Parcel.obtain();
2212                try {
2213                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2214                } catch (RemoteException e) {
2215                }
2216                data2.recycle();
2217            }
2218        }
2219        try {
2220            return super.onTransact(code, data, reply, flags);
2221        } catch (RuntimeException e) {
2222            // The activity manager only throws security exceptions, so let's
2223            // log all others.
2224            if (!(e instanceof SecurityException)) {
2225                Slog.wtf(TAG, "Activity Manager Crash", e);
2226            }
2227            throw e;
2228        }
2229    }
2230
2231    void updateCpuStats() {
2232        final long now = SystemClock.uptimeMillis();
2233        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2234            return;
2235        }
2236        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2237            synchronized (mProcessCpuThread) {
2238                mProcessCpuThread.notify();
2239            }
2240        }
2241    }
2242
2243    void updateCpuStatsNow() {
2244        synchronized (mProcessCpuTracker) {
2245            mProcessCpuMutexFree.set(false);
2246            final long now = SystemClock.uptimeMillis();
2247            boolean haveNewCpuStats = false;
2248
2249            if (MONITOR_CPU_USAGE &&
2250                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2251                mLastCpuTime.set(now);
2252                haveNewCpuStats = true;
2253                mProcessCpuTracker.update();
2254                //Slog.i(TAG, mProcessCpu.printCurrentState());
2255                //Slog.i(TAG, "Total CPU usage: "
2256                //        + mProcessCpu.getTotalCpuPercent() + "%");
2257
2258                // Slog the cpu usage if the property is set.
2259                if ("true".equals(SystemProperties.get("events.cpu"))) {
2260                    int user = mProcessCpuTracker.getLastUserTime();
2261                    int system = mProcessCpuTracker.getLastSystemTime();
2262                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2263                    int irq = mProcessCpuTracker.getLastIrqTime();
2264                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2265                    int idle = mProcessCpuTracker.getLastIdleTime();
2266
2267                    int total = user + system + iowait + irq + softIrq + idle;
2268                    if (total == 0) total = 1;
2269
2270                    EventLog.writeEvent(EventLogTags.CPU,
2271                            ((user+system+iowait+irq+softIrq) * 100) / total,
2272                            (user * 100) / total,
2273                            (system * 100) / total,
2274                            (iowait * 100) / total,
2275                            (irq * 100) / total,
2276                            (softIrq * 100) / total);
2277                }
2278            }
2279
2280            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2281            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2282            synchronized(bstats) {
2283                synchronized(mPidsSelfLocked) {
2284                    if (haveNewCpuStats) {
2285                        if (mOnBattery) {
2286                            int perc = bstats.startAddingCpuLocked();
2287                            int totalUTime = 0;
2288                            int totalSTime = 0;
2289                            final int N = mProcessCpuTracker.countStats();
2290                            for (int i=0; i<N; i++) {
2291                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2292                                if (!st.working) {
2293                                    continue;
2294                                }
2295                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2296                                int otherUTime = (st.rel_utime*perc)/100;
2297                                int otherSTime = (st.rel_stime*perc)/100;
2298                                totalUTime += otherUTime;
2299                                totalSTime += otherSTime;
2300                                if (pr != null) {
2301                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2302                                    if (ps == null || !ps.isActive()) {
2303                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2304                                                pr.info.uid, pr.processName);
2305                                    }
2306                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2307                                            st.rel_stime-otherSTime);
2308                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2309                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2310                                } else {
2311                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2312                                    if (ps == null || !ps.isActive()) {
2313                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2314                                                bstats.mapUid(st.uid), st.name);
2315                                    }
2316                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2317                                            st.rel_stime-otherSTime);
2318                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2319                                }
2320                            }
2321                            bstats.finishAddingCpuLocked(perc, totalUTime,
2322                                    totalSTime, cpuSpeedTimes);
2323                        }
2324                    }
2325                }
2326
2327                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2328                    mLastWriteTime = now;
2329                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2330                }
2331            }
2332        }
2333    }
2334
2335    @Override
2336    public void batteryNeedsCpuUpdate() {
2337        updateCpuStatsNow();
2338    }
2339
2340    @Override
2341    public void batteryPowerChanged(boolean onBattery) {
2342        // When plugging in, update the CPU stats first before changing
2343        // the plug state.
2344        updateCpuStatsNow();
2345        synchronized (this) {
2346            synchronized(mPidsSelfLocked) {
2347                mOnBattery = DEBUG_POWER ? true : onBattery;
2348            }
2349        }
2350    }
2351
2352    /**
2353     * Initialize the application bind args. These are passed to each
2354     * process when the bindApplication() IPC is sent to the process. They're
2355     * lazily setup to make sure the services are running when they're asked for.
2356     */
2357    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2358        if (mAppBindArgs == null) {
2359            mAppBindArgs = new HashMap<>();
2360
2361            // Isolated processes won't get this optimization, so that we don't
2362            // violate the rules about which services they have access to.
2363            if (!isolated) {
2364                // Setup the application init args
2365                mAppBindArgs.put("package", ServiceManager.getService("package"));
2366                mAppBindArgs.put("window", ServiceManager.getService("window"));
2367                mAppBindArgs.put(Context.ALARM_SERVICE,
2368                        ServiceManager.getService(Context.ALARM_SERVICE));
2369            }
2370        }
2371        return mAppBindArgs;
2372    }
2373
2374    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2375        if (mFocusedActivity != r) {
2376            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2377            mFocusedActivity = r;
2378            if (r.task != null && r.task.voiceInteractor != null) {
2379                startRunningVoiceLocked();
2380            } else {
2381                finishRunningVoiceLocked();
2382            }
2383            mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2384            if (r != null) {
2385                mWindowManager.setFocusedApp(r.appToken, true);
2386            }
2387            applyUpdateLockStateLocked(r);
2388        }
2389        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2390                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2391    }
2392
2393    final void clearFocusedActivity(ActivityRecord r) {
2394        if (mFocusedActivity == r) {
2395            mFocusedActivity = null;
2396        }
2397    }
2398
2399    @Override
2400    public void setFocusedStack(int stackId) {
2401        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2402        synchronized (ActivityManagerService.this) {
2403            ActivityStack stack = mStackSupervisor.getStack(stackId);
2404            if (stack != null) {
2405                ActivityRecord r = stack.topRunningActivityLocked(null);
2406                if (r != null) {
2407                    setFocusedActivityLocked(r, "setFocusedStack");
2408                }
2409            }
2410        }
2411    }
2412
2413    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2414    @Override
2415    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2416        synchronized (ActivityManagerService.this) {
2417            if (listener != null) {
2418                mTaskStackListeners.register(listener);
2419            }
2420        }
2421    }
2422
2423    @Override
2424    public void notifyActivityDrawn(IBinder token) {
2425        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2426        synchronized (this) {
2427            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2428            if (r != null) {
2429                r.task.stack.notifyActivityDrawnLocked(r);
2430            }
2431        }
2432    }
2433
2434    final void applyUpdateLockStateLocked(ActivityRecord r) {
2435        // Modifications to the UpdateLock state are done on our handler, outside
2436        // the activity manager's locks.  The new state is determined based on the
2437        // state *now* of the relevant activity record.  The object is passed to
2438        // the handler solely for logging detail, not to be consulted/modified.
2439        final boolean nextState = r != null && r.immersive;
2440        mHandler.sendMessage(
2441                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2442    }
2443
2444    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2445        Message msg = Message.obtain();
2446        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2447        msg.obj = r.task.askedCompatMode ? null : r;
2448        mHandler.sendMessage(msg);
2449    }
2450
2451    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2452            String what, Object obj, ProcessRecord srcApp) {
2453        app.lastActivityTime = now;
2454
2455        if (app.activities.size() > 0) {
2456            // Don't want to touch dependent processes that are hosting activities.
2457            return index;
2458        }
2459
2460        int lrui = mLruProcesses.lastIndexOf(app);
2461        if (lrui < 0) {
2462            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2463                    + what + " " + obj + " from " + srcApp);
2464            return index;
2465        }
2466
2467        if (lrui >= index) {
2468            // Don't want to cause this to move dependent processes *back* in the
2469            // list as if they were less frequently used.
2470            return index;
2471        }
2472
2473        if (lrui >= mLruProcessActivityStart) {
2474            // Don't want to touch dependent processes that are hosting activities.
2475            return index;
2476        }
2477
2478        mLruProcesses.remove(lrui);
2479        if (index > 0) {
2480            index--;
2481        }
2482        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2483                + " in LRU list: " + app);
2484        mLruProcesses.add(index, app);
2485        return index;
2486    }
2487
2488    final void removeLruProcessLocked(ProcessRecord app) {
2489        int lrui = mLruProcesses.lastIndexOf(app);
2490        if (lrui >= 0) {
2491            if (!app.killed) {
2492                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2493                Process.killProcessQuiet(app.pid);
2494                Process.killProcessGroup(app.info.uid, app.pid);
2495            }
2496            if (lrui <= mLruProcessActivityStart) {
2497                mLruProcessActivityStart--;
2498            }
2499            if (lrui <= mLruProcessServiceStart) {
2500                mLruProcessServiceStart--;
2501            }
2502            mLruProcesses.remove(lrui);
2503        }
2504    }
2505
2506    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2507            ProcessRecord client) {
2508        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2509                || app.treatLikeActivity;
2510        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2511        if (!activityChange && hasActivity) {
2512            // The process has activities, so we are only allowing activity-based adjustments
2513            // to move it.  It should be kept in the front of the list with other
2514            // processes that have activities, and we don't want those to change their
2515            // order except due to activity operations.
2516            return;
2517        }
2518
2519        mLruSeq++;
2520        final long now = SystemClock.uptimeMillis();
2521        app.lastActivityTime = now;
2522
2523        // First a quick reject: if the app is already at the position we will
2524        // put it, then there is nothing to do.
2525        if (hasActivity) {
2526            final int N = mLruProcesses.size();
2527            if (N > 0 && mLruProcesses.get(N-1) == app) {
2528                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2529                return;
2530            }
2531        } else {
2532            if (mLruProcessServiceStart > 0
2533                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2534                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2535                return;
2536            }
2537        }
2538
2539        int lrui = mLruProcesses.lastIndexOf(app);
2540
2541        if (app.persistent && lrui >= 0) {
2542            // We don't care about the position of persistent processes, as long as
2543            // they are in the list.
2544            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2545            return;
2546        }
2547
2548        /* In progress: compute new position first, so we can avoid doing work
2549           if the process is not actually going to move.  Not yet working.
2550        int addIndex;
2551        int nextIndex;
2552        boolean inActivity = false, inService = false;
2553        if (hasActivity) {
2554            // Process has activities, put it at the very tipsy-top.
2555            addIndex = mLruProcesses.size();
2556            nextIndex = mLruProcessServiceStart;
2557            inActivity = true;
2558        } else if (hasService) {
2559            // Process has services, put it at the top of the service list.
2560            addIndex = mLruProcessActivityStart;
2561            nextIndex = mLruProcessServiceStart;
2562            inActivity = true;
2563            inService = true;
2564        } else  {
2565            // Process not otherwise of interest, it goes to the top of the non-service area.
2566            addIndex = mLruProcessServiceStart;
2567            if (client != null) {
2568                int clientIndex = mLruProcesses.lastIndexOf(client);
2569                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2570                        + app);
2571                if (clientIndex >= 0 && addIndex > clientIndex) {
2572                    addIndex = clientIndex;
2573                }
2574            }
2575            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2576        }
2577
2578        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2579                + mLruProcessActivityStart + "): " + app);
2580        */
2581
2582        if (lrui >= 0) {
2583            if (lrui < mLruProcessActivityStart) {
2584                mLruProcessActivityStart--;
2585            }
2586            if (lrui < mLruProcessServiceStart) {
2587                mLruProcessServiceStart--;
2588            }
2589            /*
2590            if (addIndex > lrui) {
2591                addIndex--;
2592            }
2593            if (nextIndex > lrui) {
2594                nextIndex--;
2595            }
2596            */
2597            mLruProcesses.remove(lrui);
2598        }
2599
2600        /*
2601        mLruProcesses.add(addIndex, app);
2602        if (inActivity) {
2603            mLruProcessActivityStart++;
2604        }
2605        if (inService) {
2606            mLruProcessActivityStart++;
2607        }
2608        */
2609
2610        int nextIndex;
2611        if (hasActivity) {
2612            final int N = mLruProcesses.size();
2613            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2614                // Process doesn't have activities, but has clients with
2615                // activities...  move it up, but one below the top (the top
2616                // should always have a real activity).
2617                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2618                mLruProcesses.add(N-1, app);
2619                // To keep it from spamming the LRU list (by making a bunch of clients),
2620                // we will push down any other entries owned by the app.
2621                final int uid = app.info.uid;
2622                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2623                    ProcessRecord subProc = mLruProcesses.get(i);
2624                    if (subProc.info.uid == uid) {
2625                        // We want to push this one down the list.  If the process after
2626                        // it is for the same uid, however, don't do so, because we don't
2627                        // want them internally to be re-ordered.
2628                        if (mLruProcesses.get(i-1).info.uid != uid) {
2629                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2630                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2631                            ProcessRecord tmp = mLruProcesses.get(i);
2632                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2633                            mLruProcesses.set(i-1, tmp);
2634                            i--;
2635                        }
2636                    } else {
2637                        // A gap, we can stop here.
2638                        break;
2639                    }
2640                }
2641            } else {
2642                // Process has activities, put it at the very tipsy-top.
2643                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2644                mLruProcesses.add(app);
2645            }
2646            nextIndex = mLruProcessServiceStart;
2647        } else if (hasService) {
2648            // Process has services, put it at the top of the service list.
2649            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2650            mLruProcesses.add(mLruProcessActivityStart, app);
2651            nextIndex = mLruProcessServiceStart;
2652            mLruProcessActivityStart++;
2653        } else  {
2654            // Process not otherwise of interest, it goes to the top of the non-service area.
2655            int index = mLruProcessServiceStart;
2656            if (client != null) {
2657                // If there is a client, don't allow the process to be moved up higher
2658                // in the list than that client.
2659                int clientIndex = mLruProcesses.lastIndexOf(client);
2660                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2661                        + " when updating " + app);
2662                if (clientIndex <= lrui) {
2663                    // Don't allow the client index restriction to push it down farther in the
2664                    // list than it already is.
2665                    clientIndex = lrui;
2666                }
2667                if (clientIndex >= 0 && index > clientIndex) {
2668                    index = clientIndex;
2669                }
2670            }
2671            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2672            mLruProcesses.add(index, app);
2673            nextIndex = index-1;
2674            mLruProcessActivityStart++;
2675            mLruProcessServiceStart++;
2676        }
2677
2678        // If the app is currently using a content provider or service,
2679        // bump those processes as well.
2680        for (int j=app.connections.size()-1; j>=0; j--) {
2681            ConnectionRecord cr = app.connections.valueAt(j);
2682            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2683                    && cr.binding.service.app != null
2684                    && cr.binding.service.app.lruSeq != mLruSeq
2685                    && !cr.binding.service.app.persistent) {
2686                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2687                        "service connection", cr, app);
2688            }
2689        }
2690        for (int j=app.conProviders.size()-1; j>=0; j--) {
2691            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2692            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2693                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2694                        "provider reference", cpr, app);
2695            }
2696        }
2697    }
2698
2699    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2700        if (uid == Process.SYSTEM_UID) {
2701            // The system gets to run in any process.  If there are multiple
2702            // processes with the same uid, just pick the first (this
2703            // should never happen).
2704            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2705            if (procs == null) return null;
2706            final int N = procs.size();
2707            for (int i = 0; i < N; i++) {
2708                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2709            }
2710        }
2711        ProcessRecord proc = mProcessNames.get(processName, uid);
2712        if (false && proc != null && !keepIfLarge
2713                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2714                && proc.lastCachedPss >= 4000) {
2715            // Turn this condition on to cause killing to happen regularly, for testing.
2716            if (proc.baseProcessTracker != null) {
2717                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2718            }
2719            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2720        } else if (proc != null && !keepIfLarge
2721                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2722                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2723            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2724            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2725                if (proc.baseProcessTracker != null) {
2726                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2727                }
2728                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2729            }
2730        }
2731        return proc;
2732    }
2733
2734    void ensurePackageDexOpt(String packageName) {
2735        IPackageManager pm = AppGlobals.getPackageManager();
2736        try {
2737            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2738                mDidDexOpt = true;
2739            }
2740        } catch (RemoteException e) {
2741        }
2742    }
2743
2744    boolean isNextTransitionForward() {
2745        int transit = mWindowManager.getPendingAppTransition();
2746        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2747                || transit == AppTransition.TRANSIT_TASK_OPEN
2748                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2749    }
2750
2751    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2752            String processName, String abiOverride, int uid, Runnable crashHandler) {
2753        synchronized(this) {
2754            ApplicationInfo info = new ApplicationInfo();
2755            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2756            // For isolated processes, the former contains the parent's uid and the latter the
2757            // actual uid of the isolated process.
2758            // In the special case introduced by this method (which is, starting an isolated
2759            // process directly from the SystemServer without an actual parent app process) the
2760            // closest thing to a parent's uid is SYSTEM_UID.
2761            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2762            // the |isolated| logic in the ProcessRecord constructor.
2763            info.uid = Process.SYSTEM_UID;
2764            info.processName = processName;
2765            info.className = entryPoint;
2766            info.packageName = "android";
2767            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2768                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2769                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2770                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2771                    crashHandler);
2772            return proc != null ? proc.pid : 0;
2773        }
2774    }
2775
2776    final ProcessRecord startProcessLocked(String processName,
2777            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2778            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2779            boolean isolated, boolean keepIfLarge) {
2780        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2781                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2782                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2783                null /* crashHandler */);
2784    }
2785
2786    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2787            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2788            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2789            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2790        long startTime = SystemClock.elapsedRealtime();
2791        ProcessRecord app;
2792        if (!isolated) {
2793            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2794            checkTime(startTime, "startProcess: after getProcessRecord");
2795        } else {
2796            // If this is an isolated process, it can't re-use an existing process.
2797            app = null;
2798        }
2799        // We don't have to do anything more if:
2800        // (1) There is an existing application record; and
2801        // (2) The caller doesn't think it is dead, OR there is no thread
2802        //     object attached to it so we know it couldn't have crashed; and
2803        // (3) There is a pid assigned to it, so it is either starting or
2804        //     already running.
2805        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2806                + " app=" + app + " knownToBeDead=" + knownToBeDead
2807                + " thread=" + (app != null ? app.thread : null)
2808                + " pid=" + (app != null ? app.pid : -1));
2809        if (app != null && app.pid > 0) {
2810            if (!knownToBeDead || app.thread == null) {
2811                // We already have the app running, or are waiting for it to
2812                // come up (we have a pid but not yet its thread), so keep it.
2813                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2814                // If this is a new package in the process, add the package to the list
2815                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2816                checkTime(startTime, "startProcess: done, added package to proc");
2817                return app;
2818            }
2819
2820            // An application record is attached to a previous process,
2821            // clean it up now.
2822            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2823            checkTime(startTime, "startProcess: bad proc running, killing");
2824            Process.killProcessGroup(app.info.uid, app.pid);
2825            handleAppDiedLocked(app, true, true);
2826            checkTime(startTime, "startProcess: done killing old proc");
2827        }
2828
2829        String hostingNameStr = hostingName != null
2830                ? hostingName.flattenToShortString() : null;
2831
2832        if (!isolated) {
2833            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2834                // If we are in the background, then check to see if this process
2835                // is bad.  If so, we will just silently fail.
2836                if (mBadProcesses.get(info.processName, info.uid) != null) {
2837                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2838                            + "/" + info.processName);
2839                    return null;
2840                }
2841            } else {
2842                // When the user is explicitly starting a process, then clear its
2843                // crash count so that we won't make it bad until they see at
2844                // least one crash dialog again, and make the process good again
2845                // if it had been bad.
2846                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2847                        + "/" + info.processName);
2848                mProcessCrashTimes.remove(info.processName, info.uid);
2849                if (mBadProcesses.get(info.processName, info.uid) != null) {
2850                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2851                            UserHandle.getUserId(info.uid), info.uid,
2852                            info.processName);
2853                    mBadProcesses.remove(info.processName, info.uid);
2854                    if (app != null) {
2855                        app.bad = false;
2856                    }
2857                }
2858            }
2859        }
2860
2861        if (app == null) {
2862            checkTime(startTime, "startProcess: creating new process record");
2863            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2864            if (app == null) {
2865                Slog.w(TAG, "Failed making new process record for "
2866                        + processName + "/" + info.uid + " isolated=" + isolated);
2867                return null;
2868            }
2869            app.crashHandler = crashHandler;
2870            mProcessNames.put(processName, app.uid, app);
2871            if (isolated) {
2872                mIsolatedProcesses.put(app.uid, app);
2873            }
2874            checkTime(startTime, "startProcess: done creating new process record");
2875        } else {
2876            // If this is a new package in the process, add the package to the list
2877            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2878            checkTime(startTime, "startProcess: added package to existing proc");
2879        }
2880
2881        // If the system is not ready yet, then hold off on starting this
2882        // process until it is.
2883        if (!mProcessesReady
2884                && !isAllowedWhileBooting(info)
2885                && !allowWhileBooting) {
2886            if (!mProcessesOnHold.contains(app)) {
2887                mProcessesOnHold.add(app);
2888            }
2889            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2890            checkTime(startTime, "startProcess: returning with proc on hold");
2891            return app;
2892        }
2893
2894        checkTime(startTime, "startProcess: stepping in to startProcess");
2895        startProcessLocked(
2896                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2897        checkTime(startTime, "startProcess: done starting proc!");
2898        return (app.pid != 0) ? app : null;
2899    }
2900
2901    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2902        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2903    }
2904
2905    private final void startProcessLocked(ProcessRecord app,
2906            String hostingType, String hostingNameStr) {
2907        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2908                null /* entryPoint */, null /* entryPointArgs */);
2909    }
2910
2911    private final void startProcessLocked(ProcessRecord app, String hostingType,
2912            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2913        long startTime = SystemClock.elapsedRealtime();
2914        if (app.pid > 0 && app.pid != MY_PID) {
2915            checkTime(startTime, "startProcess: removing from pids map");
2916            synchronized (mPidsSelfLocked) {
2917                mPidsSelfLocked.remove(app.pid);
2918                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2919            }
2920            checkTime(startTime, "startProcess: done removing from pids map");
2921            app.setPid(0);
2922        }
2923
2924        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2925                "startProcessLocked removing on hold: " + app);
2926        mProcessesOnHold.remove(app);
2927
2928        checkTime(startTime, "startProcess: starting to update cpu stats");
2929        updateCpuStats();
2930        checkTime(startTime, "startProcess: done updating cpu stats");
2931
2932        try {
2933            int uid = app.uid;
2934
2935            int[] gids = null;
2936            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2937            if (!app.isolated) {
2938                int[] permGids = null;
2939                try {
2940                    checkTime(startTime, "startProcess: getting gids from package manager");
2941                    final PackageManager pm = mContext.getPackageManager();
2942                    permGids = pm.getPackageGids(app.info.packageName);
2943
2944                    if (Environment.isExternalStorageEmulated()) {
2945                        checkTime(startTime, "startProcess: checking external storage perm");
2946                        if (pm.checkPermission(
2947                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2948                                app.info.packageName) == PERMISSION_GRANTED) {
2949                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2950                        } else {
2951                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2952                        }
2953                    }
2954                } catch (PackageManager.NameNotFoundException e) {
2955                    Slog.w(TAG, "Unable to retrieve gids", e);
2956                }
2957
2958                /*
2959                 * Add shared application and profile GIDs so applications can share some
2960                 * resources like shared libraries and access user-wide resources
2961                 */
2962                if (permGids == null) {
2963                    gids = new int[2];
2964                } else {
2965                    gids = new int[permGids.length + 2];
2966                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2967                }
2968                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2969                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2970            }
2971            checkTime(startTime, "startProcess: building args");
2972            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2973                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2974                        && mTopComponent != null
2975                        && app.processName.equals(mTopComponent.getPackageName())) {
2976                    uid = 0;
2977                }
2978                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2979                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2980                    uid = 0;
2981                }
2982            }
2983            int debugFlags = 0;
2984            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2986                // Also turn on CheckJNI for debuggable apps. It's quite
2987                // awkward to turn on otherwise.
2988                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2989            }
2990            // Run the app in safe mode if its manifest requests so or the
2991            // system is booted in safe mode.
2992            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2993                mSafeMode == true) {
2994                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2995            }
2996            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2997                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2998            }
2999            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3000                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3001            }
3002            if ("1".equals(SystemProperties.get("debug.assert"))) {
3003                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3004            }
3005
3006            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3007            if (requiredAbi == null) {
3008                requiredAbi = Build.SUPPORTED_ABIS[0];
3009            }
3010
3011            String instructionSet = null;
3012            if (app.info.primaryCpuAbi != null) {
3013                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3014            }
3015
3016            app.gids = gids;
3017            app.requiredAbi = requiredAbi;
3018            app.instructionSet = instructionSet;
3019
3020            // Start the process.  It will either succeed and return a result containing
3021            // the PID of the new process, or else throw a RuntimeException.
3022            boolean isActivityProcess = (entryPoint == null);
3023            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3024            checkTime(startTime, "startProcess: asking zygote to start proc");
3025            Process.ProcessStartResult startResult = Process.start(entryPoint,
3026                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3027                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3028                    app.info.dataDir, entryPointArgs);
3029            checkTime(startTime, "startProcess: returned from zygote!");
3030
3031            if (app.isolated) {
3032                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3033            }
3034            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3035            checkTime(startTime, "startProcess: done updating battery stats");
3036
3037            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3038                    UserHandle.getUserId(uid), startResult.pid, uid,
3039                    app.processName, hostingType,
3040                    hostingNameStr != null ? hostingNameStr : "");
3041
3042            if (app.persistent) {
3043                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3044            }
3045
3046            checkTime(startTime, "startProcess: building log message");
3047            StringBuilder buf = mStringBuilder;
3048            buf.setLength(0);
3049            buf.append("Start proc ");
3050            buf.append(startResult.pid);
3051            buf.append(':');
3052            buf.append(app.processName);
3053            buf.append('/');
3054            UserHandle.formatUid(buf, uid);
3055            if (!isActivityProcess) {
3056                buf.append(" [");
3057                buf.append(entryPoint);
3058                buf.append("]");
3059            }
3060            buf.append(" for ");
3061            buf.append(hostingType);
3062            if (hostingNameStr != null) {
3063                buf.append(" ");
3064                buf.append(hostingNameStr);
3065            }
3066            Slog.i(TAG, buf.toString());
3067            app.setPid(startResult.pid);
3068            app.usingWrapper = startResult.usingWrapper;
3069            app.removed = false;
3070            app.killed = false;
3071            app.killedByAm = false;
3072            checkTime(startTime, "startProcess: starting to update pids map");
3073            synchronized (mPidsSelfLocked) {
3074                this.mPidsSelfLocked.put(startResult.pid, app);
3075                if (isActivityProcess) {
3076                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3077                    msg.obj = app;
3078                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3079                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3080                }
3081            }
3082            checkTime(startTime, "startProcess: done updating pids map");
3083        } catch (RuntimeException e) {
3084            // XXX do better error recovery.
3085            app.setPid(0);
3086            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3087            if (app.isolated) {
3088                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3089            }
3090            Slog.e(TAG, "Failure starting process " + app.processName, e);
3091        }
3092    }
3093
3094    void updateUsageStats(ActivityRecord component, boolean resumed) {
3095        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3096        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3097        if (resumed) {
3098            if (mUsageStatsService != null) {
3099                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3100                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3101            }
3102            synchronized (stats) {
3103                stats.noteActivityResumedLocked(component.app.uid);
3104            }
3105        } else {
3106            if (mUsageStatsService != null) {
3107                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3108                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityPausedLocked(component.app.uid);
3112            }
3113        }
3114    }
3115
3116    Intent getHomeIntent() {
3117        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3118        intent.setComponent(mTopComponent);
3119        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3120            intent.addCategory(Intent.CATEGORY_HOME);
3121        }
3122        return intent;
3123    }
3124
3125    boolean startHomeActivityLocked(int userId, String reason) {
3126        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3127                && mTopAction == null) {
3128            // We are running in factory test mode, but unable to find
3129            // the factory test app, so just sit around displaying the
3130            // error message and don't try to start anything.
3131            return false;
3132        }
3133        Intent intent = getHomeIntent();
3134        ActivityInfo aInfo =
3135            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3136        if (aInfo != null) {
3137            intent.setComponent(new ComponentName(
3138                    aInfo.applicationInfo.packageName, aInfo.name));
3139            // Don't do this if the home app is currently being
3140            // instrumented.
3141            aInfo = new ActivityInfo(aInfo);
3142            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3143            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3144                    aInfo.applicationInfo.uid, true);
3145            if (app == null || app.instrumentationClass == null) {
3146                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3147                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3148            }
3149        }
3150
3151        return true;
3152    }
3153
3154    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3155        ActivityInfo ai = null;
3156        ComponentName comp = intent.getComponent();
3157        try {
3158            if (comp != null) {
3159                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3160            } else {
3161                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3162                        intent,
3163                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3164                            flags, userId);
3165
3166                if (info != null) {
3167                    ai = info.activityInfo;
3168                }
3169            }
3170        } catch (RemoteException e) {
3171            // ignore
3172        }
3173
3174        return ai;
3175    }
3176
3177    /**
3178     * Starts the "new version setup screen" if appropriate.
3179     */
3180    void startSetupActivityLocked() {
3181        // Only do this once per boot.
3182        if (mCheckedForSetup) {
3183            return;
3184        }
3185
3186        // We will show this screen if the current one is a different
3187        // version than the last one shown, and we are not running in
3188        // low-level factory test mode.
3189        final ContentResolver resolver = mContext.getContentResolver();
3190        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3191                Settings.Global.getInt(resolver,
3192                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3193            mCheckedForSetup = true;
3194
3195            // See if we should be showing the platform update setup UI.
3196            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3197            List<ResolveInfo> ris = mContext.getPackageManager()
3198                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3199
3200            // We don't allow third party apps to replace this.
3201            ResolveInfo ri = null;
3202            for (int i=0; ris != null && i<ris.size(); i++) {
3203                if ((ris.get(i).activityInfo.applicationInfo.flags
3204                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3205                    ri = ris.get(i);
3206                    break;
3207                }
3208            }
3209
3210            if (ri != null) {
3211                String vers = ri.activityInfo.metaData != null
3212                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3213                        : null;
3214                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3215                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3216                            Intent.METADATA_SETUP_VERSION);
3217                }
3218                String lastVers = Settings.Secure.getString(
3219                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3220                if (vers != null && !vers.equals(lastVers)) {
3221                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3222                    intent.setComponent(new ComponentName(
3223                            ri.activityInfo.packageName, ri.activityInfo.name));
3224                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3225                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3226                            null);
3227                }
3228            }
3229        }
3230    }
3231
3232    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3233        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3234    }
3235
3236    void enforceNotIsolatedCaller(String caller) {
3237        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3238            throw new SecurityException("Isolated process not allowed to call " + caller);
3239        }
3240    }
3241
3242    void enforceShellRestriction(String restriction, int userHandle) {
3243        if (Binder.getCallingUid() == Process.SHELL_UID) {
3244            if (userHandle < 0
3245                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3246                throw new SecurityException("Shell does not have permission to access user "
3247                        + userHandle);
3248            }
3249        }
3250    }
3251
3252    @Override
3253    public int getFrontActivityScreenCompatMode() {
3254        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3255        synchronized (this) {
3256            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3257        }
3258    }
3259
3260    @Override
3261    public void setFrontActivityScreenCompatMode(int mode) {
3262        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3263                "setFrontActivityScreenCompatMode");
3264        synchronized (this) {
3265            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3266        }
3267    }
3268
3269    @Override
3270    public int getPackageScreenCompatMode(String packageName) {
3271        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3272        synchronized (this) {
3273            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3274        }
3275    }
3276
3277    @Override
3278    public void setPackageScreenCompatMode(String packageName, int mode) {
3279        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3280                "setPackageScreenCompatMode");
3281        synchronized (this) {
3282            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3283        }
3284    }
3285
3286    @Override
3287    public boolean getPackageAskScreenCompat(String packageName) {
3288        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3289        synchronized (this) {
3290            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3291        }
3292    }
3293
3294    @Override
3295    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3296        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3297                "setPackageAskScreenCompat");
3298        synchronized (this) {
3299            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3300        }
3301    }
3302
3303    private void dispatchProcessesChanged() {
3304        int N;
3305        synchronized (this) {
3306            N = mPendingProcessChanges.size();
3307            if (mActiveProcessChanges.length < N) {
3308                mActiveProcessChanges = new ProcessChangeItem[N];
3309            }
3310            mPendingProcessChanges.toArray(mActiveProcessChanges);
3311            mAvailProcessChanges.addAll(mPendingProcessChanges);
3312            mPendingProcessChanges.clear();
3313            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3314        }
3315
3316        int i = mProcessObservers.beginBroadcast();
3317        while (i > 0) {
3318            i--;
3319            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3320            if (observer != null) {
3321                try {
3322                    for (int j=0; j<N; j++) {
3323                        ProcessChangeItem item = mActiveProcessChanges[j];
3324                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3325                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3326                                    + item.pid + " uid=" + item.uid + ": "
3327                                    + item.foregroundActivities);
3328                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3329                                    item.foregroundActivities);
3330                        }
3331                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3332                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3333                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3334                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3335                        }
3336                    }
3337                } catch (RemoteException e) {
3338                }
3339            }
3340        }
3341        mProcessObservers.finishBroadcast();
3342    }
3343
3344    private void dispatchProcessDied(int pid, int uid) {
3345        int i = mProcessObservers.beginBroadcast();
3346        while (i > 0) {
3347            i--;
3348            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3349            if (observer != null) {
3350                try {
3351                    observer.onProcessDied(pid, uid);
3352                } catch (RemoteException e) {
3353                }
3354            }
3355        }
3356        mProcessObservers.finishBroadcast();
3357    }
3358
3359    @Override
3360    public final int startActivity(IApplicationThread caller, String callingPackage,
3361            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3362            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3363        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3364            resultWho, requestCode, startFlags, profilerInfo, options,
3365            UserHandle.getCallingUserId());
3366    }
3367
3368    @Override
3369    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3370            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3371            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivity");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivity", null);
3375        // TODO: Switch to user app stacks here.
3376        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3377                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3378                profilerInfo, null, null, options, userId, null, null);
3379    }
3380
3381    @Override
3382    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3384            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3385
3386        // This is very dangerous -- it allows you to perform a start activity (including
3387        // permission grants) as any app that may launch one of your own activities.  So
3388        // we will only allow this to be done from activities that are part of the core framework,
3389        // and then only when they are running as the system.
3390        final ActivityRecord sourceRecord;
3391        final int targetUid;
3392        final String targetPackage;
3393        synchronized (this) {
3394            if (resultTo == null) {
3395                throw new SecurityException("Must be called from an activity");
3396            }
3397            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3398            if (sourceRecord == null) {
3399                throw new SecurityException("Called with bad activity token: " + resultTo);
3400            }
3401            if (!sourceRecord.info.packageName.equals("android")) {
3402                throw new SecurityException(
3403                        "Must be called from an activity that is declared in the android package");
3404            }
3405            if (sourceRecord.app == null) {
3406                throw new SecurityException("Called without a process attached to activity");
3407            }
3408            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3409                // This is still okay, as long as this activity is running under the
3410                // uid of the original calling activity.
3411                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3412                    throw new SecurityException(
3413                            "Calling activity in uid " + sourceRecord.app.uid
3414                                    + " must be system uid or original calling uid "
3415                                    + sourceRecord.launchedFromUid);
3416                }
3417            }
3418            targetUid = sourceRecord.launchedFromUid;
3419            targetPackage = sourceRecord.launchedFromPackage;
3420        }
3421
3422        if (userId == UserHandle.USER_NULL) {
3423            userId = UserHandle.getUserId(sourceRecord.app.uid);
3424        }
3425
3426        // TODO: Switch to user app stacks here.
3427        try {
3428            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3429                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3430                    null, null, options, userId, null, null);
3431            return ret;
3432        } catch (SecurityException e) {
3433            // XXX need to figure out how to propagate to original app.
3434            // A SecurityException here is generally actually a fault of the original
3435            // calling activity (such as a fairly granting permissions), so propagate it
3436            // back to them.
3437            /*
3438            StringBuilder msg = new StringBuilder();
3439            msg.append("While launching");
3440            msg.append(intent.toString());
3441            msg.append(": ");
3442            msg.append(e.getMessage());
3443            */
3444            throw e;
3445        }
3446    }
3447
3448    @Override
3449    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3450            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3451            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3452        enforceNotIsolatedCaller("startActivityAndWait");
3453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3454                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3455        WaitResult res = new WaitResult();
3456        // TODO: Switch to user app stacks here.
3457        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3458                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3459                options, userId, null, null);
3460        return res;
3461    }
3462
3463    @Override
3464    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3465            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3466            int startFlags, Configuration config, Bundle options, int userId) {
3467        enforceNotIsolatedCaller("startActivityWithConfig");
3468        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3469                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3470        // TODO: Switch to user app stacks here.
3471        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3472                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3473                null, null, config, options, userId, null, null);
3474        return ret;
3475    }
3476
3477    @Override
3478    public int startActivityIntentSender(IApplicationThread caller,
3479            IntentSender intent, Intent fillInIntent, String resolvedType,
3480            IBinder resultTo, String resultWho, int requestCode,
3481            int flagsMask, int flagsValues, Bundle options) {
3482        enforceNotIsolatedCaller("startActivityIntentSender");
3483        // Refuse possible leaked file descriptors
3484        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3485            throw new IllegalArgumentException("File descriptors passed in Intent");
3486        }
3487
3488        IIntentSender sender = intent.getTarget();
3489        if (!(sender instanceof PendingIntentRecord)) {
3490            throw new IllegalArgumentException("Bad PendingIntent object");
3491        }
3492
3493        PendingIntentRecord pir = (PendingIntentRecord)sender;
3494
3495        synchronized (this) {
3496            // If this is coming from the currently resumed activity, it is
3497            // effectively saying that app switches are allowed at this point.
3498            final ActivityStack stack = getFocusedStack();
3499            if (stack.mResumedActivity != null &&
3500                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3501                mAppSwitchesAllowedTime = 0;
3502            }
3503        }
3504        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3505                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3506        return ret;
3507    }
3508
3509    @Override
3510    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3511            Intent intent, String resolvedType, IVoiceInteractionSession session,
3512            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3513            Bundle options, int userId) {
3514        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3515                != PackageManager.PERMISSION_GRANTED) {
3516            String msg = "Permission Denial: startVoiceActivity() from pid="
3517                    + Binder.getCallingPid()
3518                    + ", uid=" + Binder.getCallingUid()
3519                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3520            Slog.w(TAG, msg);
3521            throw new SecurityException(msg);
3522        }
3523        if (session == null || interactor == null) {
3524            throw new NullPointerException("null session or interactor");
3525        }
3526        userId = handleIncomingUser(callingPid, callingUid, userId,
3527                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3528        // TODO: Switch to user app stacks here.
3529        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3530                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3531                null, options, userId, null, null);
3532    }
3533
3534    @Override
3535    public boolean startNextMatchingActivity(IBinder callingActivity,
3536            Intent intent, Bundle options) {
3537        // Refuse possible leaked file descriptors
3538        if (intent != null && intent.hasFileDescriptors() == true) {
3539            throw new IllegalArgumentException("File descriptors passed in Intent");
3540        }
3541
3542        synchronized (this) {
3543            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3544            if (r == null) {
3545                ActivityOptions.abort(options);
3546                return false;
3547            }
3548            if (r.app == null || r.app.thread == null) {
3549                // The caller is not running...  d'oh!
3550                ActivityOptions.abort(options);
3551                return false;
3552            }
3553            intent = new Intent(intent);
3554            // The caller is not allowed to change the data.
3555            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3556            // And we are resetting to find the next component...
3557            intent.setComponent(null);
3558
3559            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3560
3561            ActivityInfo aInfo = null;
3562            try {
3563                List<ResolveInfo> resolves =
3564                    AppGlobals.getPackageManager().queryIntentActivities(
3565                            intent, r.resolvedType,
3566                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3567                            UserHandle.getCallingUserId());
3568
3569                // Look for the original activity in the list...
3570                final int N = resolves != null ? resolves.size() : 0;
3571                for (int i=0; i<N; i++) {
3572                    ResolveInfo rInfo = resolves.get(i);
3573                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3574                            && rInfo.activityInfo.name.equals(r.info.name)) {
3575                        // We found the current one...  the next matching is
3576                        // after it.
3577                        i++;
3578                        if (i<N) {
3579                            aInfo = resolves.get(i).activityInfo;
3580                        }
3581                        if (debug) {
3582                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3583                                    + "/" + r.info.name);
3584                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3585                                    + "/" + aInfo.name);
3586                        }
3587                        break;
3588                    }
3589                }
3590            } catch (RemoteException e) {
3591            }
3592
3593            if (aInfo == null) {
3594                // Nobody who is next!
3595                ActivityOptions.abort(options);
3596                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3597                return false;
3598            }
3599
3600            intent.setComponent(new ComponentName(
3601                    aInfo.applicationInfo.packageName, aInfo.name));
3602            intent.setFlags(intent.getFlags()&~(
3603                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3604                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3605                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3606                    Intent.FLAG_ACTIVITY_NEW_TASK));
3607
3608            // Okay now we need to start the new activity, replacing the
3609            // currently running activity.  This is a little tricky because
3610            // we want to start the new one as if the current one is finished,
3611            // but not finish the current one first so that there is no flicker.
3612            // And thus...
3613            final boolean wasFinishing = r.finishing;
3614            r.finishing = true;
3615
3616            // Propagate reply information over to the new activity.
3617            final ActivityRecord resultTo = r.resultTo;
3618            final String resultWho = r.resultWho;
3619            final int requestCode = r.requestCode;
3620            r.resultTo = null;
3621            if (resultTo != null) {
3622                resultTo.removeResultsLocked(r, resultWho, requestCode);
3623            }
3624
3625            final long origId = Binder.clearCallingIdentity();
3626            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3627                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3628                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3629                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3630            Binder.restoreCallingIdentity(origId);
3631
3632            r.finishing = wasFinishing;
3633            if (res != ActivityManager.START_SUCCESS) {
3634                return false;
3635            }
3636            return true;
3637        }
3638    }
3639
3640    @Override
3641    public final int startActivityFromRecents(int taskId, Bundle options) {
3642        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3643            String msg = "Permission Denial: startActivityFromRecents called without " +
3644                    START_TASKS_FROM_RECENTS;
3645            Slog.w(TAG, msg);
3646            throw new SecurityException(msg);
3647        }
3648        return startActivityFromRecentsInner(taskId, options);
3649    }
3650
3651    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3652        final TaskRecord task;
3653        final int callingUid;
3654        final String callingPackage;
3655        final Intent intent;
3656        final int userId;
3657        synchronized (this) {
3658            task = mRecentTasks.taskForIdLocked(taskId);
3659            if (task == null) {
3660                throw new IllegalArgumentException("Task " + taskId + " not found.");
3661            }
3662            if (task.getRootActivity() != null) {
3663                moveTaskToFrontLocked(task.taskId, 0, null);
3664                return ActivityManager.START_TASK_TO_FRONT;
3665            }
3666            callingUid = task.mCallingUid;
3667            callingPackage = task.mCallingPackage;
3668            intent = task.intent;
3669            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3670            userId = task.userId;
3671        }
3672        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3673                options, userId, null, task);
3674    }
3675
3676    final int startActivityInPackage(int uid, String callingPackage,
3677            Intent intent, String resolvedType, IBinder resultTo,
3678            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3679            IActivityContainer container, TaskRecord inTask) {
3680
3681        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3682                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3683
3684        // TODO: Switch to user app stacks here.
3685        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3686                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3687                null, null, null, options, userId, container, inTask);
3688        return ret;
3689    }
3690
3691    @Override
3692    public final int startActivities(IApplicationThread caller, String callingPackage,
3693            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3694            int userId) {
3695        enforceNotIsolatedCaller("startActivities");
3696        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3697                false, ALLOW_FULL_ONLY, "startActivity", null);
3698        // TODO: Switch to user app stacks here.
3699        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3700                resolvedTypes, resultTo, options, userId);
3701        return ret;
3702    }
3703
3704    final int startActivitiesInPackage(int uid, String callingPackage,
3705            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3706            Bundle options, int userId) {
3707
3708        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3709                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3710        // TODO: Switch to user app stacks here.
3711        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3712                resultTo, options, userId);
3713        return ret;
3714    }
3715
3716    @Override
3717    public void reportActivityFullyDrawn(IBinder token) {
3718        synchronized (this) {
3719            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3720            if (r == null) {
3721                return;
3722            }
3723            r.reportFullyDrawnLocked();
3724        }
3725    }
3726
3727    @Override
3728    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3729        synchronized (this) {
3730            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3731            if (r == null) {
3732                return;
3733            }
3734            if (r.task != null && r.task.mResizeable) {
3735                // Fixed screen orientation isn't supported with resizeable activities.
3736                return;
3737            }
3738            final long origId = Binder.clearCallingIdentity();
3739            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3740            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3741                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3742            if (config != null) {
3743                r.frozenBeforeDestroy = true;
3744                if (!updateConfigurationLocked(config, r, false, false)) {
3745                    mStackSupervisor.resumeTopActivitiesLocked();
3746                }
3747            }
3748            Binder.restoreCallingIdentity(origId);
3749        }
3750    }
3751
3752    @Override
3753    public int getRequestedOrientation(IBinder token) {
3754        synchronized (this) {
3755            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3756            if (r == null) {
3757                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3758            }
3759            return mWindowManager.getAppOrientation(r.appToken);
3760        }
3761    }
3762
3763    /**
3764     * This is the internal entry point for handling Activity.finish().
3765     *
3766     * @param token The Binder token referencing the Activity we want to finish.
3767     * @param resultCode Result code, if any, from this Activity.
3768     * @param resultData Result data (Intent), if any, from this Activity.
3769     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3770     *            the root Activity in the task.
3771     *
3772     * @return Returns true if the activity successfully finished, or false if it is still running.
3773     */
3774    @Override
3775    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3776            boolean finishTask) {
3777        // Refuse possible leaked file descriptors
3778        if (resultData != null && resultData.hasFileDescriptors() == true) {
3779            throw new IllegalArgumentException("File descriptors passed in Intent");
3780        }
3781
3782        synchronized(this) {
3783            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3784            if (r == null) {
3785                return true;
3786            }
3787            // Keep track of the root activity of the task before we finish it
3788            TaskRecord tr = r.task;
3789            ActivityRecord rootR = tr.getRootActivity();
3790            if (rootR == null) {
3791                Slog.w(TAG, "Finishing task with all activities already finished");
3792            }
3793            // Do not allow task to finish in Lock Task mode.
3794            if (tr == mStackSupervisor.mLockTaskModeTask) {
3795                if (rootR == r) {
3796                    Slog.i(TAG, "Not finishing task in lock task mode");
3797                    mStackSupervisor.showLockTaskToast();
3798                    return false;
3799                }
3800            }
3801            if (mController != null) {
3802                // Find the first activity that is not finishing.
3803                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3804                if (next != null) {
3805                    // ask watcher if this is allowed
3806                    boolean resumeOK = true;
3807                    try {
3808                        resumeOK = mController.activityResuming(next.packageName);
3809                    } catch (RemoteException e) {
3810                        mController = null;
3811                        Watchdog.getInstance().setActivityController(null);
3812                    }
3813
3814                    if (!resumeOK) {
3815                        Slog.i(TAG, "Not finishing activity because controller resumed");
3816                        return false;
3817                    }
3818                }
3819            }
3820            final long origId = Binder.clearCallingIdentity();
3821            try {
3822                boolean res;
3823                if (finishTask && r == rootR) {
3824                    // If requested, remove the task that is associated to this activity only if it
3825                    // was the root activity in the task. The result code and data is ignored
3826                    // because we don't support returning them across task boundaries.
3827                    res = removeTaskByIdLocked(tr.taskId, false);
3828                    if (!res) {
3829                        Slog.i(TAG, "Removing task failed to finish activity");
3830                    }
3831                } else {
3832                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3833                            resultData, "app-request", true);
3834                    if (!res) {
3835                        Slog.i(TAG, "Failed to finish by app-request");
3836                    }
3837                }
3838                return res;
3839            } finally {
3840                Binder.restoreCallingIdentity(origId);
3841            }
3842        }
3843    }
3844
3845    @Override
3846    public final void finishHeavyWeightApp() {
3847        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3848                != PackageManager.PERMISSION_GRANTED) {
3849            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3850                    + Binder.getCallingPid()
3851                    + ", uid=" + Binder.getCallingUid()
3852                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3853            Slog.w(TAG, msg);
3854            throw new SecurityException(msg);
3855        }
3856
3857        synchronized(this) {
3858            if (mHeavyWeightProcess == null) {
3859                return;
3860            }
3861
3862            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3863                    mHeavyWeightProcess.activities);
3864            for (int i=0; i<activities.size(); i++) {
3865                ActivityRecord r = activities.get(i);
3866                if (!r.finishing) {
3867                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3868                            null, "finish-heavy", true);
3869                }
3870            }
3871
3872            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3873                    mHeavyWeightProcess.userId, 0));
3874            mHeavyWeightProcess = null;
3875        }
3876    }
3877
3878    @Override
3879    public void crashApplication(int uid, int initialPid, String packageName,
3880            String message) {
3881        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3882                != PackageManager.PERMISSION_GRANTED) {
3883            String msg = "Permission Denial: crashApplication() from pid="
3884                    + Binder.getCallingPid()
3885                    + ", uid=" + Binder.getCallingUid()
3886                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3887            Slog.w(TAG, msg);
3888            throw new SecurityException(msg);
3889        }
3890
3891        synchronized(this) {
3892            ProcessRecord proc = null;
3893
3894            // Figure out which process to kill.  We don't trust that initialPid
3895            // still has any relation to current pids, so must scan through the
3896            // list.
3897            synchronized (mPidsSelfLocked) {
3898                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3899                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3900                    if (p.uid != uid) {
3901                        continue;
3902                    }
3903                    if (p.pid == initialPid) {
3904                        proc = p;
3905                        break;
3906                    }
3907                    if (p.pkgList.containsKey(packageName)) {
3908                        proc = p;
3909                    }
3910                }
3911            }
3912
3913            if (proc == null) {
3914                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3915                        + " initialPid=" + initialPid
3916                        + " packageName=" + packageName);
3917                return;
3918            }
3919
3920            if (proc.thread != null) {
3921                if (proc.pid == Process.myPid()) {
3922                    Log.w(TAG, "crashApplication: trying to crash self!");
3923                    return;
3924                }
3925                long ident = Binder.clearCallingIdentity();
3926                try {
3927                    proc.thread.scheduleCrash(message);
3928                } catch (RemoteException e) {
3929                }
3930                Binder.restoreCallingIdentity(ident);
3931            }
3932        }
3933    }
3934
3935    @Override
3936    public final void finishSubActivity(IBinder token, String resultWho,
3937            int requestCode) {
3938        synchronized(this) {
3939            final long origId = Binder.clearCallingIdentity();
3940            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3941            if (r != null) {
3942                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3943            }
3944            Binder.restoreCallingIdentity(origId);
3945        }
3946    }
3947
3948    @Override
3949    public boolean finishActivityAffinity(IBinder token) {
3950        synchronized(this) {
3951            final long origId = Binder.clearCallingIdentity();
3952            try {
3953                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3954
3955                ActivityRecord rootR = r.task.getRootActivity();
3956                // Do not allow task to finish in Lock Task mode.
3957                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3958                    if (rootR == r) {
3959                        mStackSupervisor.showLockTaskToast();
3960                        return false;
3961                    }
3962                }
3963                boolean res = false;
3964                if (r != null) {
3965                    res = r.task.stack.finishActivityAffinityLocked(r);
3966                }
3967                return res;
3968            } finally {
3969                Binder.restoreCallingIdentity(origId);
3970            }
3971        }
3972    }
3973
3974    @Override
3975    public void finishVoiceTask(IVoiceInteractionSession session) {
3976        synchronized(this) {
3977            final long origId = Binder.clearCallingIdentity();
3978            try {
3979                mStackSupervisor.finishVoiceTask(session);
3980            } finally {
3981                Binder.restoreCallingIdentity(origId);
3982            }
3983        }
3984
3985    }
3986
3987    @Override
3988    public boolean releaseActivityInstance(IBinder token) {
3989        synchronized(this) {
3990            final long origId = Binder.clearCallingIdentity();
3991            try {
3992                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3993                if (r.task == null || r.task.stack == null) {
3994                    return false;
3995                }
3996                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
3997            } finally {
3998                Binder.restoreCallingIdentity(origId);
3999            }
4000        }
4001    }
4002
4003    @Override
4004    public void releaseSomeActivities(IApplicationThread appInt) {
4005        synchronized(this) {
4006            final long origId = Binder.clearCallingIdentity();
4007            try {
4008                ProcessRecord app = getRecordForAppLocked(appInt);
4009                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4010            } finally {
4011                Binder.restoreCallingIdentity(origId);
4012            }
4013        }
4014    }
4015
4016    @Override
4017    public boolean willActivityBeVisible(IBinder token) {
4018        synchronized(this) {
4019            ActivityStack stack = ActivityRecord.getStackLocked(token);
4020            if (stack != null) {
4021                return stack.willActivityBeVisibleLocked(token);
4022            }
4023            return false;
4024        }
4025    }
4026
4027    @Override
4028    public void overridePendingTransition(IBinder token, String packageName,
4029            int enterAnim, int exitAnim) {
4030        synchronized(this) {
4031            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4032            if (self == null) {
4033                return;
4034            }
4035
4036            final long origId = Binder.clearCallingIdentity();
4037
4038            if (self.state == ActivityState.RESUMED
4039                    || self.state == ActivityState.PAUSING) {
4040                mWindowManager.overridePendingAppTransition(packageName,
4041                        enterAnim, exitAnim, null);
4042            }
4043
4044            Binder.restoreCallingIdentity(origId);
4045        }
4046    }
4047
4048    /**
4049     * Main function for removing an existing process from the activity manager
4050     * as a result of that process going away.  Clears out all connections
4051     * to the process.
4052     */
4053    private final void handleAppDiedLocked(ProcessRecord app,
4054            boolean restarting, boolean allowRestart) {
4055        int pid = app.pid;
4056        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4057        if (!kept && !restarting) {
4058            removeLruProcessLocked(app);
4059            if (pid > 0) {
4060                ProcessList.remove(pid);
4061            }
4062        }
4063
4064        if (mProfileProc == app) {
4065            clearProfilerLocked();
4066        }
4067
4068        // Remove this application's activities from active lists.
4069        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4070
4071        app.activities.clear();
4072
4073        if (app.instrumentationClass != null) {
4074            Slog.w(TAG, "Crash of app " + app.processName
4075                  + " running instrumentation " + app.instrumentationClass);
4076            Bundle info = new Bundle();
4077            info.putString("shortMsg", "Process crashed.");
4078            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4079        }
4080
4081        if (!restarting) {
4082            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4083                // If there was nothing to resume, and we are not already
4084                // restarting this process, but there is a visible activity that
4085                // is hosted by the process...  then make sure all visible
4086                // activities are running, taking care of restarting this
4087                // process.
4088                if (hasVisibleActivities) {
4089                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4090                }
4091            }
4092        }
4093    }
4094
4095    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4096        IBinder threadBinder = thread.asBinder();
4097        // Find the application record.
4098        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4099            ProcessRecord rec = mLruProcesses.get(i);
4100            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4101                return i;
4102            }
4103        }
4104        return -1;
4105    }
4106
4107    final ProcessRecord getRecordForAppLocked(
4108            IApplicationThread thread) {
4109        if (thread == null) {
4110            return null;
4111        }
4112
4113        int appIndex = getLRURecordIndexForAppLocked(thread);
4114        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4115    }
4116
4117    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4118        // If there are no longer any background processes running,
4119        // and the app that died was not running instrumentation,
4120        // then tell everyone we are now low on memory.
4121        boolean haveBg = false;
4122        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4123            ProcessRecord rec = mLruProcesses.get(i);
4124            if (rec.thread != null
4125                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4126                haveBg = true;
4127                break;
4128            }
4129        }
4130
4131        if (!haveBg) {
4132            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4133            if (doReport) {
4134                long now = SystemClock.uptimeMillis();
4135                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4136                    doReport = false;
4137                } else {
4138                    mLastMemUsageReportTime = now;
4139                }
4140            }
4141            final ArrayList<ProcessMemInfo> memInfos
4142                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4143            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4144            long now = SystemClock.uptimeMillis();
4145            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4146                ProcessRecord rec = mLruProcesses.get(i);
4147                if (rec == dyingProc || rec.thread == null) {
4148                    continue;
4149                }
4150                if (doReport) {
4151                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4152                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4153                }
4154                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4155                    // The low memory report is overriding any current
4156                    // state for a GC request.  Make sure to do
4157                    // heavy/important/visible/foreground processes first.
4158                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4159                        rec.lastRequestedGc = 0;
4160                    } else {
4161                        rec.lastRequestedGc = rec.lastLowMemory;
4162                    }
4163                    rec.reportLowMemory = true;
4164                    rec.lastLowMemory = now;
4165                    mProcessesToGc.remove(rec);
4166                    addProcessToGcListLocked(rec);
4167                }
4168            }
4169            if (doReport) {
4170                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4171                mHandler.sendMessage(msg);
4172            }
4173            scheduleAppGcsLocked();
4174        }
4175    }
4176
4177    final void appDiedLocked(ProcessRecord app) {
4178       appDiedLocked(app, app.pid, app.thread);
4179    }
4180
4181    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4182        // First check if this ProcessRecord is actually active for the pid.
4183        synchronized (mPidsSelfLocked) {
4184            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4185            if (curProc != app) {
4186                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4187                return;
4188            }
4189        }
4190
4191        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4192        synchronized (stats) {
4193            stats.noteProcessDiedLocked(app.info.uid, pid);
4194        }
4195
4196        if (!app.killed) {
4197            Process.killProcessQuiet(pid);
4198            Process.killProcessGroup(app.info.uid, pid);
4199            app.killed = true;
4200        }
4201
4202        // Clean up already done if the process has been re-started.
4203        if (app.pid == pid && app.thread != null &&
4204                app.thread.asBinder() == thread.asBinder()) {
4205            boolean doLowMem = app.instrumentationClass == null;
4206            boolean doOomAdj = doLowMem;
4207            if (!app.killedByAm) {
4208                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4209                        + ") has died");
4210                mAllowLowerMemLevel = true;
4211            } else {
4212                // Note that we always want to do oom adj to update our state with the
4213                // new number of procs.
4214                mAllowLowerMemLevel = false;
4215                doLowMem = false;
4216            }
4217            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4218            if (DEBUG_CLEANUP) Slog.v(
4219                TAG, "Dying app: " + app + ", pid: " + pid
4220                + ", thread: " + thread.asBinder());
4221            handleAppDiedLocked(app, false, true);
4222
4223            if (doOomAdj) {
4224                updateOomAdjLocked();
4225            }
4226            if (doLowMem) {
4227                doLowMemReportIfNeededLocked(app);
4228            }
4229        } else if (app.pid != pid) {
4230            // A new process has already been started.
4231            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4232                    + ") has died and restarted (pid " + app.pid + ").");
4233            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4234        } else if (DEBUG_PROCESSES) {
4235            Slog.d(TAG, "Received spurious death notification for thread "
4236                    + thread.asBinder());
4237        }
4238    }
4239
4240    /**
4241     * If a stack trace dump file is configured, dump process stack traces.
4242     * @param clearTraces causes the dump file to be erased prior to the new
4243     *    traces being written, if true; when false, the new traces will be
4244     *    appended to any existing file content.
4245     * @param firstPids of dalvik VM processes to dump stack traces for first
4246     * @param lastPids of dalvik VM processes to dump stack traces for last
4247     * @param nativeProcs optional list of native process names to dump stack crawls
4248     * @return file containing stack traces, or null if no dump file is configured
4249     */
4250    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4251            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4252        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4253        if (tracesPath == null || tracesPath.length() == 0) {
4254            return null;
4255        }
4256
4257        File tracesFile = new File(tracesPath);
4258        try {
4259            File tracesDir = tracesFile.getParentFile();
4260            if (!tracesDir.exists()) {
4261                tracesDir.mkdirs();
4262                if (!SELinux.restorecon(tracesDir)) {
4263                    return null;
4264                }
4265            }
4266            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4267
4268            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4269            tracesFile.createNewFile();
4270            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4271        } catch (IOException e) {
4272            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4273            return null;
4274        }
4275
4276        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4277        return tracesFile;
4278    }
4279
4280    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4281            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4282        // Use a FileObserver to detect when traces finish writing.
4283        // The order of traces is considered important to maintain for legibility.
4284        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4285            @Override
4286            public synchronized void onEvent(int event, String path) { notify(); }
4287        };
4288
4289        try {
4290            observer.startWatching();
4291
4292            // First collect all of the stacks of the most important pids.
4293            if (firstPids != null) {
4294                try {
4295                    int num = firstPids.size();
4296                    for (int i = 0; i < num; i++) {
4297                        synchronized (observer) {
4298                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4299                            observer.wait(200);  // Wait for write-close, give up after 200msec
4300                        }
4301                    }
4302                } catch (InterruptedException e) {
4303                    Slog.wtf(TAG, e);
4304                }
4305            }
4306
4307            // Next collect the stacks of the native pids
4308            if (nativeProcs != null) {
4309                int[] pids = Process.getPidsForCommands(nativeProcs);
4310                if (pids != null) {
4311                    for (int pid : pids) {
4312                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4313                    }
4314                }
4315            }
4316
4317            // Lastly, measure CPU usage.
4318            if (processCpuTracker != null) {
4319                processCpuTracker.init();
4320                System.gc();
4321                processCpuTracker.update();
4322                try {
4323                    synchronized (processCpuTracker) {
4324                        processCpuTracker.wait(500); // measure over 1/2 second.
4325                    }
4326                } catch (InterruptedException e) {
4327                }
4328                processCpuTracker.update();
4329
4330                // We'll take the stack crawls of just the top apps using CPU.
4331                final int N = processCpuTracker.countWorkingStats();
4332                int numProcs = 0;
4333                for (int i=0; i<N && numProcs<5; i++) {
4334                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4335                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4336                        numProcs++;
4337                        try {
4338                            synchronized (observer) {
4339                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4340                                observer.wait(200);  // Wait for write-close, give up after 200msec
4341                            }
4342                        } catch (InterruptedException e) {
4343                            Slog.wtf(TAG, e);
4344                        }
4345
4346                    }
4347                }
4348            }
4349        } finally {
4350            observer.stopWatching();
4351        }
4352    }
4353
4354    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4355        if (true || IS_USER_BUILD) {
4356            return;
4357        }
4358        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4359        if (tracesPath == null || tracesPath.length() == 0) {
4360            return;
4361        }
4362
4363        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4364        StrictMode.allowThreadDiskWrites();
4365        try {
4366            final File tracesFile = new File(tracesPath);
4367            final File tracesDir = tracesFile.getParentFile();
4368            final File tracesTmp = new File(tracesDir, "__tmp__");
4369            try {
4370                if (!tracesDir.exists()) {
4371                    tracesDir.mkdirs();
4372                    if (!SELinux.restorecon(tracesDir.getPath())) {
4373                        return;
4374                    }
4375                }
4376                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4377
4378                if (tracesFile.exists()) {
4379                    tracesTmp.delete();
4380                    tracesFile.renameTo(tracesTmp);
4381                }
4382                StringBuilder sb = new StringBuilder();
4383                Time tobj = new Time();
4384                tobj.set(System.currentTimeMillis());
4385                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4386                sb.append(": ");
4387                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4388                sb.append(" since ");
4389                sb.append(msg);
4390                FileOutputStream fos = new FileOutputStream(tracesFile);
4391                fos.write(sb.toString().getBytes());
4392                if (app == null) {
4393                    fos.write("\n*** No application process!".getBytes());
4394                }
4395                fos.close();
4396                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4397            } catch (IOException e) {
4398                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4399                return;
4400            }
4401
4402            if (app != null) {
4403                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4404                firstPids.add(app.pid);
4405                dumpStackTraces(tracesPath, firstPids, null, null, null);
4406            }
4407
4408            File lastTracesFile = null;
4409            File curTracesFile = null;
4410            for (int i=9; i>=0; i--) {
4411                String name = String.format(Locale.US, "slow%02d.txt", i);
4412                curTracesFile = new File(tracesDir, name);
4413                if (curTracesFile.exists()) {
4414                    if (lastTracesFile != null) {
4415                        curTracesFile.renameTo(lastTracesFile);
4416                    } else {
4417                        curTracesFile.delete();
4418                    }
4419                }
4420                lastTracesFile = curTracesFile;
4421            }
4422            tracesFile.renameTo(curTracesFile);
4423            if (tracesTmp.exists()) {
4424                tracesTmp.renameTo(tracesFile);
4425            }
4426        } finally {
4427            StrictMode.setThreadPolicy(oldPolicy);
4428        }
4429    }
4430
4431    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4432            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4433        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4434        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4435
4436        if (mController != null) {
4437            try {
4438                // 0 == continue, -1 = kill process immediately
4439                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4440                if (res < 0 && app.pid != MY_PID) {
4441                    app.kill("anr", true);
4442                }
4443            } catch (RemoteException e) {
4444                mController = null;
4445                Watchdog.getInstance().setActivityController(null);
4446            }
4447        }
4448
4449        long anrTime = SystemClock.uptimeMillis();
4450        if (MONITOR_CPU_USAGE) {
4451            updateCpuStatsNow();
4452        }
4453
4454        synchronized (this) {
4455            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4456            if (mShuttingDown) {
4457                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4458                return;
4459            } else if (app.notResponding) {
4460                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4461                return;
4462            } else if (app.crashing) {
4463                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4464                return;
4465            }
4466
4467            // In case we come through here for the same app before completing
4468            // this one, mark as anring now so we will bail out.
4469            app.notResponding = true;
4470
4471            // Log the ANR to the event log.
4472            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4473                    app.processName, app.info.flags, annotation);
4474
4475            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4476            firstPids.add(app.pid);
4477
4478            int parentPid = app.pid;
4479            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4480            if (parentPid != app.pid) firstPids.add(parentPid);
4481
4482            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4483
4484            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4485                ProcessRecord r = mLruProcesses.get(i);
4486                if (r != null && r.thread != null) {
4487                    int pid = r.pid;
4488                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4489                        if (r.persistent) {
4490                            firstPids.add(pid);
4491                        } else {
4492                            lastPids.put(pid, Boolean.TRUE);
4493                        }
4494                    }
4495                }
4496            }
4497        }
4498
4499        // Log the ANR to the main log.
4500        StringBuilder info = new StringBuilder();
4501        info.setLength(0);
4502        info.append("ANR in ").append(app.processName);
4503        if (activity != null && activity.shortComponentName != null) {
4504            info.append(" (").append(activity.shortComponentName).append(")");
4505        }
4506        info.append("\n");
4507        info.append("PID: ").append(app.pid).append("\n");
4508        if (annotation != null) {
4509            info.append("Reason: ").append(annotation).append("\n");
4510        }
4511        if (parent != null && parent != activity) {
4512            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4513        }
4514
4515        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4516
4517        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4518                NATIVE_STACKS_OF_INTEREST);
4519
4520        String cpuInfo = null;
4521        if (MONITOR_CPU_USAGE) {
4522            updateCpuStatsNow();
4523            synchronized (mProcessCpuTracker) {
4524                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4525            }
4526            info.append(processCpuTracker.printCurrentLoad());
4527            info.append(cpuInfo);
4528        }
4529
4530        info.append(processCpuTracker.printCurrentState(anrTime));
4531
4532        Slog.e(TAG, info.toString());
4533        if (tracesFile == null) {
4534            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4535            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4536        }
4537
4538        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4539                cpuInfo, tracesFile, null);
4540
4541        if (mController != null) {
4542            try {
4543                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4544                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4545                if (res != 0) {
4546                    if (res < 0 && app.pid != MY_PID) {
4547                        app.kill("anr", true);
4548                    } else {
4549                        synchronized (this) {
4550                            mServices.scheduleServiceTimeoutLocked(app);
4551                        }
4552                    }
4553                    return;
4554                }
4555            } catch (RemoteException e) {
4556                mController = null;
4557                Watchdog.getInstance().setActivityController(null);
4558            }
4559        }
4560
4561        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4562        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4563                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4564
4565        synchronized (this) {
4566            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4567
4568            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4569                app.kill("bg anr", true);
4570                return;
4571            }
4572
4573            // Set the app's notResponding state, and look up the errorReportReceiver
4574            makeAppNotRespondingLocked(app,
4575                    activity != null ? activity.shortComponentName : null,
4576                    annotation != null ? "ANR " + annotation : "ANR",
4577                    info.toString());
4578
4579            // Bring up the infamous App Not Responding dialog
4580            Message msg = Message.obtain();
4581            HashMap<String, Object> map = new HashMap<String, Object>();
4582            msg.what = SHOW_NOT_RESPONDING_MSG;
4583            msg.obj = map;
4584            msg.arg1 = aboveSystem ? 1 : 0;
4585            map.put("app", app);
4586            if (activity != null) {
4587                map.put("activity", activity);
4588            }
4589
4590            mHandler.sendMessage(msg);
4591        }
4592    }
4593
4594    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4595        if (!mLaunchWarningShown) {
4596            mLaunchWarningShown = true;
4597            mHandler.post(new Runnable() {
4598                @Override
4599                public void run() {
4600                    synchronized (ActivityManagerService.this) {
4601                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4602                        d.show();
4603                        mHandler.postDelayed(new Runnable() {
4604                            @Override
4605                            public void run() {
4606                                synchronized (ActivityManagerService.this) {
4607                                    d.dismiss();
4608                                    mLaunchWarningShown = false;
4609                                }
4610                            }
4611                        }, 4000);
4612                    }
4613                }
4614            });
4615        }
4616    }
4617
4618    @Override
4619    public boolean clearApplicationUserData(final String packageName,
4620            final IPackageDataObserver observer, int userId) {
4621        enforceNotIsolatedCaller("clearApplicationUserData");
4622        int uid = Binder.getCallingUid();
4623        int pid = Binder.getCallingPid();
4624        userId = handleIncomingUser(pid, uid,
4625                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4626        long callingId = Binder.clearCallingIdentity();
4627        try {
4628            IPackageManager pm = AppGlobals.getPackageManager();
4629            int pkgUid = -1;
4630            synchronized(this) {
4631                try {
4632                    pkgUid = pm.getPackageUid(packageName, userId);
4633                } catch (RemoteException e) {
4634                }
4635                if (pkgUid == -1) {
4636                    Slog.w(TAG, "Invalid packageName: " + packageName);
4637                    if (observer != null) {
4638                        try {
4639                            observer.onRemoveCompleted(packageName, false);
4640                        } catch (RemoteException e) {
4641                            Slog.i(TAG, "Observer no longer exists.");
4642                        }
4643                    }
4644                    return false;
4645                }
4646                if (uid == pkgUid || checkComponentPermission(
4647                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4648                        pid, uid, -1, true)
4649                        == PackageManager.PERMISSION_GRANTED) {
4650                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4651                } else {
4652                    throw new SecurityException("PID " + pid + " does not have permission "
4653                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4654                                    + " of package " + packageName);
4655                }
4656
4657                // Remove all tasks match the cleared application package and user
4658                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4659                    final TaskRecord tr = mRecentTasks.get(i);
4660                    final String taskPackageName =
4661                            tr.getBaseIntent().getComponent().getPackageName();
4662                    if (tr.userId != userId) continue;
4663                    if (!taskPackageName.equals(packageName)) continue;
4664                    removeTaskByIdLocked(tr.taskId, false);
4665                }
4666            }
4667
4668            try {
4669                // Clear application user data
4670                pm.clearApplicationUserData(packageName, observer, userId);
4671
4672                synchronized(this) {
4673                    // Remove all permissions granted from/to this package
4674                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4675                }
4676
4677                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4678                        Uri.fromParts("package", packageName, null));
4679                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4680                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4681                        null, null, 0, null, null, null, false, false, userId);
4682            } catch (RemoteException e) {
4683            }
4684        } finally {
4685            Binder.restoreCallingIdentity(callingId);
4686        }
4687        return true;
4688    }
4689
4690    @Override
4691    public void killBackgroundProcesses(final String packageName, int userId) {
4692        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4693                != PackageManager.PERMISSION_GRANTED &&
4694                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4695                        != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703
4704        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4705                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            synchronized(this) {
4710                int appId = -1;
4711                try {
4712                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4713                } catch (RemoteException e) {
4714                }
4715                if (appId == -1) {
4716                    Slog.w(TAG, "Invalid packageName: " + packageName);
4717                    return;
4718                }
4719                killPackageProcessesLocked(packageName, appId, userId,
4720                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(callingId);
4724        }
4725    }
4726
4727    @Override
4728    public void killAllBackgroundProcesses() {
4729        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4730                != PackageManager.PERMISSION_GRANTED) {
4731            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4732                    + Binder.getCallingPid()
4733                    + ", uid=" + Binder.getCallingUid()
4734                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4735            Slog.w(TAG, msg);
4736            throw new SecurityException(msg);
4737        }
4738
4739        long callingId = Binder.clearCallingIdentity();
4740        try {
4741            synchronized(this) {
4742                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4743                final int NP = mProcessNames.getMap().size();
4744                for (int ip=0; ip<NP; ip++) {
4745                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4746                    final int NA = apps.size();
4747                    for (int ia=0; ia<NA; ia++) {
4748                        ProcessRecord app = apps.valueAt(ia);
4749                        if (app.persistent) {
4750                            // we don't kill persistent processes
4751                            continue;
4752                        }
4753                        if (app.removed) {
4754                            procs.add(app);
4755                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4756                            app.removed = true;
4757                            procs.add(app);
4758                        }
4759                    }
4760                }
4761
4762                int N = procs.size();
4763                for (int i=0; i<N; i++) {
4764                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4765                }
4766                mAllowLowerMemLevel = true;
4767                updateOomAdjLocked();
4768                doLowMemReportIfNeededLocked(null);
4769            }
4770        } finally {
4771            Binder.restoreCallingIdentity(callingId);
4772        }
4773    }
4774
4775    @Override
4776    public void forceStopPackage(final String packageName, int userId) {
4777        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4778                != PackageManager.PERMISSION_GRANTED) {
4779            String msg = "Permission Denial: forceStopPackage() from pid="
4780                    + Binder.getCallingPid()
4781                    + ", uid=" + Binder.getCallingUid()
4782                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4783            Slog.w(TAG, msg);
4784            throw new SecurityException(msg);
4785        }
4786        final int callingPid = Binder.getCallingPid();
4787        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4788                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4789        long callingId = Binder.clearCallingIdentity();
4790        try {
4791            IPackageManager pm = AppGlobals.getPackageManager();
4792            synchronized(this) {
4793                int[] users = userId == UserHandle.USER_ALL
4794                        ? getUsersLocked() : new int[] { userId };
4795                for (int user : users) {
4796                    int pkgUid = -1;
4797                    try {
4798                        pkgUid = pm.getPackageUid(packageName, user);
4799                    } catch (RemoteException e) {
4800                    }
4801                    if (pkgUid == -1) {
4802                        Slog.w(TAG, "Invalid packageName: " + packageName);
4803                        continue;
4804                    }
4805                    try {
4806                        pm.setPackageStoppedState(packageName, true, user);
4807                    } catch (RemoteException e) {
4808                    } catch (IllegalArgumentException e) {
4809                        Slog.w(TAG, "Failed trying to unstop package "
4810                                + packageName + ": " + e);
4811                    }
4812                    if (isUserRunningLocked(user, false)) {
4813                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4814                    }
4815                }
4816            }
4817        } finally {
4818            Binder.restoreCallingIdentity(callingId);
4819        }
4820    }
4821
4822    @Override
4823    public void addPackageDependency(String packageName) {
4824        synchronized (this) {
4825            int callingPid = Binder.getCallingPid();
4826            if (callingPid == Process.myPid()) {
4827                //  Yeah, um, no.
4828                return;
4829            }
4830            ProcessRecord proc;
4831            synchronized (mPidsSelfLocked) {
4832                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4833            }
4834            if (proc != null) {
4835                if (proc.pkgDeps == null) {
4836                    proc.pkgDeps = new ArraySet<String>(1);
4837                }
4838                proc.pkgDeps.add(packageName);
4839            }
4840        }
4841    }
4842
4843    /*
4844     * The pkg name and app id have to be specified.
4845     */
4846    @Override
4847    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4848        if (pkg == null) {
4849            return;
4850        }
4851        // Make sure the uid is valid.
4852        if (appid < 0) {
4853            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4854            return;
4855        }
4856        int callerUid = Binder.getCallingUid();
4857        // Only the system server can kill an application
4858        if (callerUid == Process.SYSTEM_UID) {
4859            // Post an aysnc message to kill the application
4860            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4861            msg.arg1 = appid;
4862            msg.arg2 = 0;
4863            Bundle bundle = new Bundle();
4864            bundle.putString("pkg", pkg);
4865            bundle.putString("reason", reason);
4866            msg.obj = bundle;
4867            mHandler.sendMessage(msg);
4868        } else {
4869            throw new SecurityException(callerUid + " cannot kill pkg: " +
4870                    pkg);
4871        }
4872    }
4873
4874    @Override
4875    public void closeSystemDialogs(String reason) {
4876        enforceNotIsolatedCaller("closeSystemDialogs");
4877
4878        final int pid = Binder.getCallingPid();
4879        final int uid = Binder.getCallingUid();
4880        final long origId = Binder.clearCallingIdentity();
4881        try {
4882            synchronized (this) {
4883                // Only allow this from foreground processes, so that background
4884                // applications can't abuse it to prevent system UI from being shown.
4885                if (uid >= Process.FIRST_APPLICATION_UID) {
4886                    ProcessRecord proc;
4887                    synchronized (mPidsSelfLocked) {
4888                        proc = mPidsSelfLocked.get(pid);
4889                    }
4890                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4891                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4892                                + " from background process " + proc);
4893                        return;
4894                    }
4895                }
4896                closeSystemDialogsLocked(reason);
4897            }
4898        } finally {
4899            Binder.restoreCallingIdentity(origId);
4900        }
4901    }
4902
4903    void closeSystemDialogsLocked(String reason) {
4904        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4905        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4906                | Intent.FLAG_RECEIVER_FOREGROUND);
4907        if (reason != null) {
4908            intent.putExtra("reason", reason);
4909        }
4910        mWindowManager.closeSystemDialogs(reason);
4911
4912        mStackSupervisor.closeSystemDialogsLocked();
4913
4914        broadcastIntentLocked(null, null, intent, null,
4915                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4916                Process.SYSTEM_UID, UserHandle.USER_ALL);
4917    }
4918
4919    @Override
4920    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4921        enforceNotIsolatedCaller("getProcessMemoryInfo");
4922        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4923        for (int i=pids.length-1; i>=0; i--) {
4924            ProcessRecord proc;
4925            int oomAdj;
4926            synchronized (this) {
4927                synchronized (mPidsSelfLocked) {
4928                    proc = mPidsSelfLocked.get(pids[i]);
4929                    oomAdj = proc != null ? proc.setAdj : 0;
4930                }
4931            }
4932            infos[i] = new Debug.MemoryInfo();
4933            Debug.getMemoryInfo(pids[i], infos[i]);
4934            if (proc != null) {
4935                synchronized (this) {
4936                    if (proc.thread != null && proc.setAdj == oomAdj) {
4937                        // Record this for posterity if the process has been stable.
4938                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4939                                infos[i].getTotalUss(), false, proc.pkgList);
4940                    }
4941                }
4942            }
4943        }
4944        return infos;
4945    }
4946
4947    @Override
4948    public long[] getProcessPss(int[] pids) {
4949        enforceNotIsolatedCaller("getProcessPss");
4950        long[] pss = new long[pids.length];
4951        for (int i=pids.length-1; i>=0; i--) {
4952            ProcessRecord proc;
4953            int oomAdj;
4954            synchronized (this) {
4955                synchronized (mPidsSelfLocked) {
4956                    proc = mPidsSelfLocked.get(pids[i]);
4957                    oomAdj = proc != null ? proc.setAdj : 0;
4958                }
4959            }
4960            long[] tmpUss = new long[1];
4961            pss[i] = Debug.getPss(pids[i], tmpUss, null);
4962            if (proc != null) {
4963                synchronized (this) {
4964                    if (proc.thread != null && proc.setAdj == oomAdj) {
4965                        // Record this for posterity if the process has been stable.
4966                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4967                    }
4968                }
4969            }
4970        }
4971        return pss;
4972    }
4973
4974    @Override
4975    public void killApplicationProcess(String processName, int uid) {
4976        if (processName == null) {
4977            return;
4978        }
4979
4980        int callerUid = Binder.getCallingUid();
4981        // Only the system server can kill an application
4982        if (callerUid == Process.SYSTEM_UID) {
4983            synchronized (this) {
4984                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4985                if (app != null && app.thread != null) {
4986                    try {
4987                        app.thread.scheduleSuicide();
4988                    } catch (RemoteException e) {
4989                        // If the other end already died, then our work here is done.
4990                    }
4991                } else {
4992                    Slog.w(TAG, "Process/uid not found attempting kill of "
4993                            + processName + " / " + uid);
4994                }
4995            }
4996        } else {
4997            throw new SecurityException(callerUid + " cannot kill app process: " +
4998                    processName);
4999        }
5000    }
5001
5002    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5003        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5004                false, true, false, false, UserHandle.getUserId(uid), reason);
5005        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5006                Uri.fromParts("package", packageName, null));
5007        if (!mProcessesReady) {
5008            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5009                    | Intent.FLAG_RECEIVER_FOREGROUND);
5010        }
5011        intent.putExtra(Intent.EXTRA_UID, uid);
5012        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5013        broadcastIntentLocked(null, null, intent,
5014                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5015                false, false,
5016                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5017    }
5018
5019    private void forceStopUserLocked(int userId, String reason) {
5020        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5021        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5022        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5023                | Intent.FLAG_RECEIVER_FOREGROUND);
5024        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5025        broadcastIntentLocked(null, null, intent,
5026                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5027                false, false,
5028                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5029    }
5030
5031    private final boolean killPackageProcessesLocked(String packageName, int appId,
5032            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5033            boolean doit, boolean evenPersistent, String reason) {
5034        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5035
5036        // Remove all processes this package may have touched: all with the
5037        // same UID (except for the system or root user), and all whose name
5038        // matches the package name.
5039        final int NP = mProcessNames.getMap().size();
5040        for (int ip=0; ip<NP; ip++) {
5041            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5042            final int NA = apps.size();
5043            for (int ia=0; ia<NA; ia++) {
5044                ProcessRecord app = apps.valueAt(ia);
5045                if (app.persistent && !evenPersistent) {
5046                    // we don't kill persistent processes
5047                    continue;
5048                }
5049                if (app.removed) {
5050                    if (doit) {
5051                        procs.add(app);
5052                    }
5053                    continue;
5054                }
5055
5056                // Skip process if it doesn't meet our oom adj requirement.
5057                if (app.setAdj < minOomAdj) {
5058                    continue;
5059                }
5060
5061                // If no package is specified, we call all processes under the
5062                // give user id.
5063                if (packageName == null) {
5064                    if (app.userId != userId) {
5065                        continue;
5066                    }
5067                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5068                        continue;
5069                    }
5070                // Package has been specified, we want to hit all processes
5071                // that match it.  We need to qualify this by the processes
5072                // that are running under the specified app and user ID.
5073                } else {
5074                    final boolean isDep = app.pkgDeps != null
5075                            && app.pkgDeps.contains(packageName);
5076                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5077                        continue;
5078                    }
5079                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5080                        continue;
5081                    }
5082                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5083                        continue;
5084                    }
5085                }
5086
5087                // Process has passed all conditions, kill it!
5088                if (!doit) {
5089                    return true;
5090                }
5091                app.removed = true;
5092                procs.add(app);
5093            }
5094        }
5095
5096        int N = procs.size();
5097        for (int i=0; i<N; i++) {
5098            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5099        }
5100        updateOomAdjLocked();
5101        return N > 0;
5102    }
5103
5104    private final boolean forceStopPackageLocked(String name, int appId,
5105            boolean callerWillRestart, boolean purgeCache, boolean doit,
5106            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5107        int i;
5108        int N;
5109
5110        if (userId == UserHandle.USER_ALL && name == null) {
5111            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5112        }
5113
5114        if (appId < 0 && name != null) {
5115            try {
5116                appId = UserHandle.getAppId(
5117                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5118            } catch (RemoteException e) {
5119            }
5120        }
5121
5122        if (doit) {
5123            if (name != null) {
5124                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5125                        + " user=" + userId + ": " + reason);
5126            } else {
5127                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5128            }
5129
5130            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5131            for (int ip=pmap.size()-1; ip>=0; ip--) {
5132                SparseArray<Long> ba = pmap.valueAt(ip);
5133                for (i=ba.size()-1; i>=0; i--) {
5134                    boolean remove = false;
5135                    final int entUid = ba.keyAt(i);
5136                    if (name != null) {
5137                        if (userId == UserHandle.USER_ALL) {
5138                            if (UserHandle.getAppId(entUid) == appId) {
5139                                remove = true;
5140                            }
5141                        } else {
5142                            if (entUid == UserHandle.getUid(userId, appId)) {
5143                                remove = true;
5144                            }
5145                        }
5146                    } else if (UserHandle.getUserId(entUid) == userId) {
5147                        remove = true;
5148                    }
5149                    if (remove) {
5150                        ba.removeAt(i);
5151                    }
5152                }
5153                if (ba.size() == 0) {
5154                    pmap.removeAt(ip);
5155                }
5156            }
5157        }
5158
5159        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5160                -100, callerWillRestart, true, doit, evenPersistent,
5161                name == null ? ("stop user " + userId) : ("stop " + name));
5162
5163        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5164            if (!doit) {
5165                return true;
5166            }
5167            didSomething = true;
5168        }
5169
5170        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5171            if (!doit) {
5172                return true;
5173            }
5174            didSomething = true;
5175        }
5176
5177        if (name == null) {
5178            // Remove all sticky broadcasts from this user.
5179            mStickyBroadcasts.remove(userId);
5180        }
5181
5182        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5183        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5184                userId, providers)) {
5185            if (!doit) {
5186                return true;
5187            }
5188            didSomething = true;
5189        }
5190        N = providers.size();
5191        for (i=0; i<N; i++) {
5192            removeDyingProviderLocked(null, providers.get(i), true);
5193        }
5194
5195        // Remove transient permissions granted from/to this package/user
5196        removeUriPermissionsForPackageLocked(name, userId, false);
5197
5198        if (name == null || uninstalling) {
5199            // Remove pending intents.  For now we only do this when force
5200            // stopping users, because we have some problems when doing this
5201            // for packages -- app widgets are not currently cleaned up for
5202            // such packages, so they can be left with bad pending intents.
5203            if (mIntentSenderRecords.size() > 0) {
5204                Iterator<WeakReference<PendingIntentRecord>> it
5205                        = mIntentSenderRecords.values().iterator();
5206                while (it.hasNext()) {
5207                    WeakReference<PendingIntentRecord> wpir = it.next();
5208                    if (wpir == null) {
5209                        it.remove();
5210                        continue;
5211                    }
5212                    PendingIntentRecord pir = wpir.get();
5213                    if (pir == null) {
5214                        it.remove();
5215                        continue;
5216                    }
5217                    if (name == null) {
5218                        // Stopping user, remove all objects for the user.
5219                        if (pir.key.userId != userId) {
5220                            // Not the same user, skip it.
5221                            continue;
5222                        }
5223                    } else {
5224                        if (UserHandle.getAppId(pir.uid) != appId) {
5225                            // Different app id, skip it.
5226                            continue;
5227                        }
5228                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5229                            // Different user, skip it.
5230                            continue;
5231                        }
5232                        if (!pir.key.packageName.equals(name)) {
5233                            // Different package, skip it.
5234                            continue;
5235                        }
5236                    }
5237                    if (!doit) {
5238                        return true;
5239                    }
5240                    didSomething = true;
5241                    it.remove();
5242                    pir.canceled = true;
5243                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5244                        pir.key.activity.pendingResults.remove(pir.ref);
5245                    }
5246                }
5247            }
5248        }
5249
5250        if (doit) {
5251            if (purgeCache && name != null) {
5252                AttributeCache ac = AttributeCache.instance();
5253                if (ac != null) {
5254                    ac.removePackage(name);
5255                }
5256            }
5257            if (mBooted) {
5258                mStackSupervisor.resumeTopActivitiesLocked();
5259                mStackSupervisor.scheduleIdleLocked();
5260            }
5261        }
5262
5263        return didSomething;
5264    }
5265
5266    private final boolean removeProcessLocked(ProcessRecord app,
5267            boolean callerWillRestart, boolean allowRestart, String reason) {
5268        final String name = app.processName;
5269        final int uid = app.uid;
5270        if (DEBUG_PROCESSES) Slog.d(
5271            TAG, "Force removing proc " + app.toShortString() + " (" + name
5272            + "/" + uid + ")");
5273
5274        mProcessNames.remove(name, uid);
5275        mIsolatedProcesses.remove(app.uid);
5276        if (mHeavyWeightProcess == app) {
5277            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5278                    mHeavyWeightProcess.userId, 0));
5279            mHeavyWeightProcess = null;
5280        }
5281        boolean needRestart = false;
5282        if (app.pid > 0 && app.pid != MY_PID) {
5283            int pid = app.pid;
5284            synchronized (mPidsSelfLocked) {
5285                mPidsSelfLocked.remove(pid);
5286                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5287            }
5288            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5289            if (app.isolated) {
5290                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5291            }
5292            app.kill(reason, true);
5293            handleAppDiedLocked(app, true, allowRestart);
5294            removeLruProcessLocked(app);
5295
5296            if (app.persistent && !app.isolated) {
5297                if (!callerWillRestart) {
5298                    addAppLocked(app.info, false, null /* ABI override */);
5299                } else {
5300                    needRestart = true;
5301                }
5302            }
5303        } else {
5304            mRemovedProcesses.add(app);
5305        }
5306
5307        return needRestart;
5308    }
5309
5310    private final void processStartTimedOutLocked(ProcessRecord app) {
5311        final int pid = app.pid;
5312        boolean gone = false;
5313        synchronized (mPidsSelfLocked) {
5314            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5315            if (knownApp != null && knownApp.thread == null) {
5316                mPidsSelfLocked.remove(pid);
5317                gone = true;
5318            }
5319        }
5320
5321        if (gone) {
5322            Slog.w(TAG, "Process " + app + " failed to attach");
5323            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5324                    pid, app.uid, app.processName);
5325            mProcessNames.remove(app.processName, app.uid);
5326            mIsolatedProcesses.remove(app.uid);
5327            if (mHeavyWeightProcess == app) {
5328                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5329                        mHeavyWeightProcess.userId, 0));
5330                mHeavyWeightProcess = null;
5331            }
5332            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5333            if (app.isolated) {
5334                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5335            }
5336            // Take care of any launching providers waiting for this process.
5337            checkAppInLaunchingProvidersLocked(app, true);
5338            // Take care of any services that are waiting for the process.
5339            mServices.processStartTimedOutLocked(app);
5340            app.kill("start timeout", true);
5341            removeLruProcessLocked(app);
5342            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5343                Slog.w(TAG, "Unattached app died before backup, skipping");
5344                try {
5345                    IBackupManager bm = IBackupManager.Stub.asInterface(
5346                            ServiceManager.getService(Context.BACKUP_SERVICE));
5347                    bm.agentDisconnected(app.info.packageName);
5348                } catch (RemoteException e) {
5349                    // Can't happen; the backup manager is local
5350                }
5351            }
5352            if (isPendingBroadcastProcessLocked(pid)) {
5353                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5354                skipPendingBroadcastLocked(pid);
5355            }
5356        } else {
5357            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5358        }
5359    }
5360
5361    private final boolean attachApplicationLocked(IApplicationThread thread,
5362            int pid) {
5363
5364        // Find the application record that is being attached...  either via
5365        // the pid if we are running in multiple processes, or just pull the
5366        // next app record if we are emulating process with anonymous threads.
5367        ProcessRecord app;
5368        if (pid != MY_PID && pid >= 0) {
5369            synchronized (mPidsSelfLocked) {
5370                app = mPidsSelfLocked.get(pid);
5371            }
5372        } else {
5373            app = null;
5374        }
5375
5376        if (app == null) {
5377            Slog.w(TAG, "No pending application record for pid " + pid
5378                    + " (IApplicationThread " + thread + "); dropping process");
5379            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5380            if (pid > 0 && pid != MY_PID) {
5381                Process.killProcessQuiet(pid);
5382                //TODO: Process.killProcessGroup(app.info.uid, pid);
5383            } else {
5384                try {
5385                    thread.scheduleExit();
5386                } catch (Exception e) {
5387                    // Ignore exceptions.
5388                }
5389            }
5390            return false;
5391        }
5392
5393        // If this application record is still attached to a previous
5394        // process, clean it up now.
5395        if (app.thread != null) {
5396            handleAppDiedLocked(app, true, true);
5397        }
5398
5399        // Tell the process all about itself.
5400
5401        if (localLOGV) Slog.v(
5402                TAG, "Binding process pid " + pid + " to record " + app);
5403
5404        final String processName = app.processName;
5405        try {
5406            AppDeathRecipient adr = new AppDeathRecipient(
5407                    app, pid, thread);
5408            thread.asBinder().linkToDeath(adr, 0);
5409            app.deathRecipient = adr;
5410        } catch (RemoteException e) {
5411            app.resetPackageList(mProcessStats);
5412            startProcessLocked(app, "link fail", processName);
5413            return false;
5414        }
5415
5416        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5417
5418        app.makeActive(thread, mProcessStats);
5419        app.curAdj = app.setAdj = -100;
5420        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5421        app.forcingToForeground = null;
5422        updateProcessForegroundLocked(app, false, false);
5423        app.hasShownUi = false;
5424        app.debugging = false;
5425        app.cached = false;
5426        app.killedByAm = false;
5427
5428        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5429
5430        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5431        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5432
5433        if (!normalMode) {
5434            Slog.i(TAG, "Launching preboot mode app: " + app);
5435        }
5436
5437        if (localLOGV) Slog.v(
5438            TAG, "New app record " + app
5439            + " thread=" + thread.asBinder() + " pid=" + pid);
5440        try {
5441            int testMode = IApplicationThread.DEBUG_OFF;
5442            if (mDebugApp != null && mDebugApp.equals(processName)) {
5443                testMode = mWaitForDebugger
5444                    ? IApplicationThread.DEBUG_WAIT
5445                    : IApplicationThread.DEBUG_ON;
5446                app.debugging = true;
5447                if (mDebugTransient) {
5448                    mDebugApp = mOrigDebugApp;
5449                    mWaitForDebugger = mOrigWaitForDebugger;
5450                }
5451            }
5452            String profileFile = app.instrumentationProfileFile;
5453            ParcelFileDescriptor profileFd = null;
5454            int samplingInterval = 0;
5455            boolean profileAutoStop = false;
5456            if (mProfileApp != null && mProfileApp.equals(processName)) {
5457                mProfileProc = app;
5458                profileFile = mProfileFile;
5459                profileFd = mProfileFd;
5460                samplingInterval = mSamplingInterval;
5461                profileAutoStop = mAutoStopProfiler;
5462            }
5463            boolean enableOpenGlTrace = false;
5464            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5465                enableOpenGlTrace = true;
5466                mOpenGlTraceApp = null;
5467            }
5468
5469            // If the app is being launched for restore or full backup, set it up specially
5470            boolean isRestrictedBackupMode = false;
5471            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5472                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5473                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5474                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5475            }
5476
5477            ensurePackageDexOpt(app.instrumentationInfo != null
5478                    ? app.instrumentationInfo.packageName
5479                    : app.info.packageName);
5480            if (app.instrumentationClass != null) {
5481                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5482            }
5483            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5484                    + processName + " with config " + mConfiguration);
5485            ApplicationInfo appInfo = app.instrumentationInfo != null
5486                    ? app.instrumentationInfo : app.info;
5487            app.compat = compatibilityInfoForPackageLocked(appInfo);
5488            if (profileFd != null) {
5489                profileFd = profileFd.dup();
5490            }
5491            ProfilerInfo profilerInfo = profileFile == null ? null
5492                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5493            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5494                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5495                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5496                    isRestrictedBackupMode || !normalMode, app.persistent,
5497                    new Configuration(mConfiguration), app.compat,
5498                    getCommonServicesLocked(app.isolated),
5499                    mCoreSettingsObserver.getCoreSettingsLocked());
5500            updateLruProcessLocked(app, false, null);
5501            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5502        } catch (Exception e) {
5503            // todo: Yikes!  What should we do?  For now we will try to
5504            // start another process, but that could easily get us in
5505            // an infinite loop of restarting processes...
5506            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5507
5508            app.resetPackageList(mProcessStats);
5509            app.unlinkDeathRecipient();
5510            startProcessLocked(app, "bind fail", processName);
5511            return false;
5512        }
5513
5514        // Remove this record from the list of starting applications.
5515        mPersistentStartingProcesses.remove(app);
5516        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5517                "Attach application locked removing on hold: " + app);
5518        mProcessesOnHold.remove(app);
5519
5520        boolean badApp = false;
5521        boolean didSomething = false;
5522
5523        // See if the top visible activity is waiting to run in this process...
5524        if (normalMode) {
5525            try {
5526                if (mStackSupervisor.attachApplicationLocked(app)) {
5527                    didSomething = true;
5528                }
5529            } catch (Exception e) {
5530                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5531                badApp = true;
5532            }
5533        }
5534
5535        // Find any services that should be running in this process...
5536        if (!badApp) {
5537            try {
5538                didSomething |= mServices.attachApplicationLocked(app, processName);
5539            } catch (Exception e) {
5540                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5541                badApp = true;
5542            }
5543        }
5544
5545        // Check if a next-broadcast receiver is in this process...
5546        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5547            try {
5548                didSomething |= sendPendingBroadcastsLocked(app);
5549            } catch (Exception e) {
5550                // If the app died trying to launch the receiver we declare it 'bad'
5551                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5552                badApp = true;
5553            }
5554        }
5555
5556        // Check whether the next backup agent is in this process...
5557        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5558            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5559            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5560            try {
5561                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5562                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5563                        mBackupTarget.backupMode);
5564            } catch (Exception e) {
5565                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5566                badApp = true;
5567            }
5568        }
5569
5570        if (badApp) {
5571            app.kill("error during init", true);
5572            handleAppDiedLocked(app, false, true);
5573            return false;
5574        }
5575
5576        if (!didSomething) {
5577            updateOomAdjLocked();
5578        }
5579
5580        return true;
5581    }
5582
5583    @Override
5584    public final void attachApplication(IApplicationThread thread) {
5585        synchronized (this) {
5586            int callingPid = Binder.getCallingPid();
5587            final long origId = Binder.clearCallingIdentity();
5588            attachApplicationLocked(thread, callingPid);
5589            Binder.restoreCallingIdentity(origId);
5590        }
5591    }
5592
5593    @Override
5594    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5595        final long origId = Binder.clearCallingIdentity();
5596        synchronized (this) {
5597            ActivityStack stack = ActivityRecord.getStackLocked(token);
5598            if (stack != null) {
5599                ActivityRecord r =
5600                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5601                if (stopProfiling) {
5602                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5603                        try {
5604                            mProfileFd.close();
5605                        } catch (IOException e) {
5606                        }
5607                        clearProfilerLocked();
5608                    }
5609                }
5610            }
5611        }
5612        Binder.restoreCallingIdentity(origId);
5613    }
5614
5615    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5616        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5617                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5618    }
5619
5620    void enableScreenAfterBoot() {
5621        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5622                SystemClock.uptimeMillis());
5623        mWindowManager.enableScreenAfterBoot();
5624
5625        synchronized (this) {
5626            updateEventDispatchingLocked();
5627        }
5628    }
5629
5630    @Override
5631    public void showBootMessage(final CharSequence msg, final boolean always) {
5632        if (Binder.getCallingUid() != Process.myUid()) {
5633            // These days only the core system can call this, so apps can't get in
5634            // the way of what we show about running them.
5635        }
5636        mWindowManager.showBootMessage(msg, always);
5637    }
5638
5639    @Override
5640    public void keyguardWaitingForActivityDrawn() {
5641        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5642        final long token = Binder.clearCallingIdentity();
5643        try {
5644            synchronized (this) {
5645                if (DEBUG_LOCKSCREEN) logLockScreen("");
5646                mWindowManager.keyguardWaitingForActivityDrawn();
5647                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5648                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5649                    updateSleepIfNeededLocked();
5650                }
5651            }
5652        } finally {
5653            Binder.restoreCallingIdentity(token);
5654        }
5655    }
5656
5657    final void finishBooting() {
5658        synchronized (this) {
5659            if (!mBootAnimationComplete) {
5660                mCallFinishBooting = true;
5661                return;
5662            }
5663            mCallFinishBooting = false;
5664        }
5665
5666        ArraySet<String> completedIsas = new ArraySet<String>();
5667        for (String abi : Build.SUPPORTED_ABIS) {
5668            Process.establishZygoteConnectionForAbi(abi);
5669            final String instructionSet = VMRuntime.getInstructionSet(abi);
5670            if (!completedIsas.contains(instructionSet)) {
5671                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5672                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5673                }
5674                completedIsas.add(instructionSet);
5675            }
5676        }
5677
5678        IntentFilter pkgFilter = new IntentFilter();
5679        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5680        pkgFilter.addDataScheme("package");
5681        mContext.registerReceiver(new BroadcastReceiver() {
5682            @Override
5683            public void onReceive(Context context, Intent intent) {
5684                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5685                if (pkgs != null) {
5686                    for (String pkg : pkgs) {
5687                        synchronized (ActivityManagerService.this) {
5688                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5689                                    0, "finished booting")) {
5690                                setResultCode(Activity.RESULT_OK);
5691                                return;
5692                            }
5693                        }
5694                    }
5695                }
5696            }
5697        }, pkgFilter);
5698
5699        // Let system services know.
5700        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5701
5702        synchronized (this) {
5703            // Ensure that any processes we had put on hold are now started
5704            // up.
5705            final int NP = mProcessesOnHold.size();
5706            if (NP > 0) {
5707                ArrayList<ProcessRecord> procs =
5708                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5709                for (int ip=0; ip<NP; ip++) {
5710                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5711                            + procs.get(ip));
5712                    startProcessLocked(procs.get(ip), "on-hold", null);
5713                }
5714            }
5715
5716            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5717                // Start looking for apps that are abusing wake locks.
5718                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5719                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5720                // Tell anyone interested that we are done booting!
5721                SystemProperties.set("sys.boot_completed", "1");
5722
5723                // And trigger dev.bootcomplete if we are not showing encryption progress
5724                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5725                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5726                    SystemProperties.set("dev.bootcomplete", "1");
5727                }
5728                for (int i=0; i<mStartedUsers.size(); i++) {
5729                    UserStartedState uss = mStartedUsers.valueAt(i);
5730                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5731                        uss.mState = UserStartedState.STATE_RUNNING;
5732                        final int userId = mStartedUsers.keyAt(i);
5733                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5734                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5735                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5736                        broadcastIntentLocked(null, null, intent, null,
5737                                new IIntentReceiver.Stub() {
5738                                    @Override
5739                                    public void performReceive(Intent intent, int resultCode,
5740                                            String data, Bundle extras, boolean ordered,
5741                                            boolean sticky, int sendingUser) {
5742                                        synchronized (ActivityManagerService.this) {
5743                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5744                                                    true, false);
5745                                        }
5746                                    }
5747                                },
5748                                0, null, null,
5749                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5750                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5751                                userId);
5752                    }
5753                }
5754                scheduleStartProfilesLocked();
5755            }
5756        }
5757    }
5758
5759    @Override
5760    public void bootAnimationComplete() {
5761        final boolean callFinishBooting;
5762        synchronized (this) {
5763            callFinishBooting = mCallFinishBooting;
5764            mBootAnimationComplete = true;
5765        }
5766        if (callFinishBooting) {
5767            finishBooting();
5768        }
5769    }
5770
5771    @Override
5772    public void systemBackupRestored() {
5773        synchronized (this) {
5774            if (mSystemReady) {
5775                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5776            } else {
5777                Slog.w(TAG, "System backup restored before system is ready");
5778            }
5779        }
5780    }
5781
5782    final void ensureBootCompleted() {
5783        boolean booting;
5784        boolean enableScreen;
5785        synchronized (this) {
5786            booting = mBooting;
5787            mBooting = false;
5788            enableScreen = !mBooted;
5789            mBooted = true;
5790        }
5791
5792        if (booting) {
5793            finishBooting();
5794        }
5795
5796        if (enableScreen) {
5797            enableScreenAfterBoot();
5798        }
5799    }
5800
5801    @Override
5802    public final void activityResumed(IBinder token) {
5803        final long origId = Binder.clearCallingIdentity();
5804        synchronized(this) {
5805            ActivityStack stack = ActivityRecord.getStackLocked(token);
5806            if (stack != null) {
5807                ActivityRecord.activityResumedLocked(token);
5808            }
5809        }
5810        Binder.restoreCallingIdentity(origId);
5811    }
5812
5813    @Override
5814    public final void activityPaused(IBinder token) {
5815        final long origId = Binder.clearCallingIdentity();
5816        synchronized(this) {
5817            ActivityStack stack = ActivityRecord.getStackLocked(token);
5818            if (stack != null) {
5819                stack.activityPausedLocked(token, false);
5820            }
5821        }
5822        Binder.restoreCallingIdentity(origId);
5823    }
5824
5825    @Override
5826    public final void activityStopped(IBinder token, Bundle icicle,
5827            PersistableBundle persistentState, CharSequence description) {
5828        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5829
5830        // Refuse possible leaked file descriptors
5831        if (icicle != null && icicle.hasFileDescriptors()) {
5832            throw new IllegalArgumentException("File descriptors passed in Bundle");
5833        }
5834
5835        final long origId = Binder.clearCallingIdentity();
5836
5837        synchronized (this) {
5838            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5839            if (r != null) {
5840                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5841            }
5842        }
5843
5844        trimApplications();
5845
5846        Binder.restoreCallingIdentity(origId);
5847    }
5848
5849    @Override
5850    public final void activityDestroyed(IBinder token) {
5851        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5852        synchronized (this) {
5853            ActivityStack stack = ActivityRecord.getStackLocked(token);
5854            if (stack != null) {
5855                stack.activityDestroyedLocked(token, "activityDestroyed");
5856            }
5857        }
5858    }
5859
5860    @Override
5861    public final void backgroundResourcesReleased(IBinder token) {
5862        final long origId = Binder.clearCallingIdentity();
5863        try {
5864            synchronized (this) {
5865                ActivityStack stack = ActivityRecord.getStackLocked(token);
5866                if (stack != null) {
5867                    stack.backgroundResourcesReleased();
5868                }
5869            }
5870        } finally {
5871            Binder.restoreCallingIdentity(origId);
5872        }
5873    }
5874
5875    @Override
5876    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5877        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5878    }
5879
5880    @Override
5881    public final void notifyEnterAnimationComplete(IBinder token) {
5882        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5883    }
5884
5885    @Override
5886    public String getCallingPackage(IBinder token) {
5887        synchronized (this) {
5888            ActivityRecord r = getCallingRecordLocked(token);
5889            return r != null ? r.info.packageName : null;
5890        }
5891    }
5892
5893    @Override
5894    public ComponentName getCallingActivity(IBinder token) {
5895        synchronized (this) {
5896            ActivityRecord r = getCallingRecordLocked(token);
5897            return r != null ? r.intent.getComponent() : null;
5898        }
5899    }
5900
5901    private ActivityRecord getCallingRecordLocked(IBinder token) {
5902        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5903        if (r == null) {
5904            return null;
5905        }
5906        return r.resultTo;
5907    }
5908
5909    @Override
5910    public ComponentName getActivityClassForToken(IBinder token) {
5911        synchronized(this) {
5912            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5913            if (r == null) {
5914                return null;
5915            }
5916            return r.intent.getComponent();
5917        }
5918    }
5919
5920    @Override
5921    public String getPackageForToken(IBinder token) {
5922        synchronized(this) {
5923            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5924            if (r == null) {
5925                return null;
5926            }
5927            return r.packageName;
5928        }
5929    }
5930
5931    @Override
5932    public IIntentSender getIntentSender(int type,
5933            String packageName, IBinder token, String resultWho,
5934            int requestCode, Intent[] intents, String[] resolvedTypes,
5935            int flags, Bundle options, int userId) {
5936        enforceNotIsolatedCaller("getIntentSender");
5937        // Refuse possible leaked file descriptors
5938        if (intents != null) {
5939            if (intents.length < 1) {
5940                throw new IllegalArgumentException("Intents array length must be >= 1");
5941            }
5942            for (int i=0; i<intents.length; i++) {
5943                Intent intent = intents[i];
5944                if (intent != null) {
5945                    if (intent.hasFileDescriptors()) {
5946                        throw new IllegalArgumentException("File descriptors passed in Intent");
5947                    }
5948                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5949                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5950                        throw new IllegalArgumentException(
5951                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5952                    }
5953                    intents[i] = new Intent(intent);
5954                }
5955            }
5956            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5957                throw new IllegalArgumentException(
5958                        "Intent array length does not match resolvedTypes length");
5959            }
5960        }
5961        if (options != null) {
5962            if (options.hasFileDescriptors()) {
5963                throw new IllegalArgumentException("File descriptors passed in options");
5964            }
5965        }
5966
5967        synchronized(this) {
5968            int callingUid = Binder.getCallingUid();
5969            int origUserId = userId;
5970            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5971                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5972                    ALLOW_NON_FULL, "getIntentSender", null);
5973            if (origUserId == UserHandle.USER_CURRENT) {
5974                // We don't want to evaluate this until the pending intent is
5975                // actually executed.  However, we do want to always do the
5976                // security checking for it above.
5977                userId = UserHandle.USER_CURRENT;
5978            }
5979            try {
5980                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5981                    int uid = AppGlobals.getPackageManager()
5982                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5983                    if (!UserHandle.isSameApp(callingUid, uid)) {
5984                        String msg = "Permission Denial: getIntentSender() from pid="
5985                            + Binder.getCallingPid()
5986                            + ", uid=" + Binder.getCallingUid()
5987                            + ", (need uid=" + uid + ")"
5988                            + " is not allowed to send as package " + packageName;
5989                        Slog.w(TAG, msg);
5990                        throw new SecurityException(msg);
5991                    }
5992                }
5993
5994                return getIntentSenderLocked(type, packageName, callingUid, userId,
5995                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5996
5997            } catch (RemoteException e) {
5998                throw new SecurityException(e);
5999            }
6000        }
6001    }
6002
6003    IIntentSender getIntentSenderLocked(int type, String packageName,
6004            int callingUid, int userId, IBinder token, String resultWho,
6005            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6006            Bundle options) {
6007        if (DEBUG_MU)
6008            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6009        ActivityRecord activity = null;
6010        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6011            activity = ActivityRecord.isInStackLocked(token);
6012            if (activity == null) {
6013                return null;
6014            }
6015            if (activity.finishing) {
6016                return null;
6017            }
6018        }
6019
6020        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6021        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6022        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6023        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6024                |PendingIntent.FLAG_UPDATE_CURRENT);
6025
6026        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6027                type, packageName, activity, resultWho,
6028                requestCode, intents, resolvedTypes, flags, options, userId);
6029        WeakReference<PendingIntentRecord> ref;
6030        ref = mIntentSenderRecords.get(key);
6031        PendingIntentRecord rec = ref != null ? ref.get() : null;
6032        if (rec != null) {
6033            if (!cancelCurrent) {
6034                if (updateCurrent) {
6035                    if (rec.key.requestIntent != null) {
6036                        rec.key.requestIntent.replaceExtras(intents != null ?
6037                                intents[intents.length - 1] : null);
6038                    }
6039                    if (intents != null) {
6040                        intents[intents.length-1] = rec.key.requestIntent;
6041                        rec.key.allIntents = intents;
6042                        rec.key.allResolvedTypes = resolvedTypes;
6043                    } else {
6044                        rec.key.allIntents = null;
6045                        rec.key.allResolvedTypes = null;
6046                    }
6047                }
6048                return rec;
6049            }
6050            rec.canceled = true;
6051            mIntentSenderRecords.remove(key);
6052        }
6053        if (noCreate) {
6054            return rec;
6055        }
6056        rec = new PendingIntentRecord(this, key, callingUid);
6057        mIntentSenderRecords.put(key, rec.ref);
6058        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6059            if (activity.pendingResults == null) {
6060                activity.pendingResults
6061                        = new HashSet<WeakReference<PendingIntentRecord>>();
6062            }
6063            activity.pendingResults.add(rec.ref);
6064        }
6065        return rec;
6066    }
6067
6068    @Override
6069    public void cancelIntentSender(IIntentSender sender) {
6070        if (!(sender instanceof PendingIntentRecord)) {
6071            return;
6072        }
6073        synchronized(this) {
6074            PendingIntentRecord rec = (PendingIntentRecord)sender;
6075            try {
6076                int uid = AppGlobals.getPackageManager()
6077                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6078                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6079                    String msg = "Permission Denial: cancelIntentSender() from pid="
6080                        + Binder.getCallingPid()
6081                        + ", uid=" + Binder.getCallingUid()
6082                        + " is not allowed to cancel packges "
6083                        + rec.key.packageName;
6084                    Slog.w(TAG, msg);
6085                    throw new SecurityException(msg);
6086                }
6087            } catch (RemoteException e) {
6088                throw new SecurityException(e);
6089            }
6090            cancelIntentSenderLocked(rec, true);
6091        }
6092    }
6093
6094    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6095        rec.canceled = true;
6096        mIntentSenderRecords.remove(rec.key);
6097        if (cleanActivity && rec.key.activity != null) {
6098            rec.key.activity.pendingResults.remove(rec.ref);
6099        }
6100    }
6101
6102    @Override
6103    public String getPackageForIntentSender(IIntentSender pendingResult) {
6104        if (!(pendingResult instanceof PendingIntentRecord)) {
6105            return null;
6106        }
6107        try {
6108            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6109            return res.key.packageName;
6110        } catch (ClassCastException e) {
6111        }
6112        return null;
6113    }
6114
6115    @Override
6116    public int getUidForIntentSender(IIntentSender sender) {
6117        if (sender instanceof PendingIntentRecord) {
6118            try {
6119                PendingIntentRecord res = (PendingIntentRecord)sender;
6120                return res.uid;
6121            } catch (ClassCastException e) {
6122            }
6123        }
6124        return -1;
6125    }
6126
6127    @Override
6128    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6129        if (!(pendingResult instanceof PendingIntentRecord)) {
6130            return false;
6131        }
6132        try {
6133            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6134            if (res.key.allIntents == null) {
6135                return false;
6136            }
6137            for (int i=0; i<res.key.allIntents.length; i++) {
6138                Intent intent = res.key.allIntents[i];
6139                if (intent.getPackage() != null && intent.getComponent() != null) {
6140                    return false;
6141                }
6142            }
6143            return true;
6144        } catch (ClassCastException e) {
6145        }
6146        return false;
6147    }
6148
6149    @Override
6150    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6151        if (!(pendingResult instanceof PendingIntentRecord)) {
6152            return false;
6153        }
6154        try {
6155            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6156            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6157                return true;
6158            }
6159            return false;
6160        } catch (ClassCastException e) {
6161        }
6162        return false;
6163    }
6164
6165    @Override
6166    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6167        if (!(pendingResult instanceof PendingIntentRecord)) {
6168            return null;
6169        }
6170        try {
6171            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6172            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6173        } catch (ClassCastException e) {
6174        }
6175        return null;
6176    }
6177
6178    @Override
6179    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6180        if (!(pendingResult instanceof PendingIntentRecord)) {
6181            return null;
6182        }
6183        try {
6184            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6185            Intent intent = res.key.requestIntent;
6186            if (intent != null) {
6187                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6188                        || res.lastTagPrefix.equals(prefix))) {
6189                    return res.lastTag;
6190                }
6191                res.lastTagPrefix = prefix;
6192                StringBuilder sb = new StringBuilder(128);
6193                if (prefix != null) {
6194                    sb.append(prefix);
6195                }
6196                if (intent.getAction() != null) {
6197                    sb.append(intent.getAction());
6198                } else if (intent.getComponent() != null) {
6199                    intent.getComponent().appendShortString(sb);
6200                } else {
6201                    sb.append("?");
6202                }
6203                return res.lastTag = sb.toString();
6204            }
6205        } catch (ClassCastException e) {
6206        }
6207        return null;
6208    }
6209
6210    @Override
6211    public void setProcessLimit(int max) {
6212        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6213                "setProcessLimit()");
6214        synchronized (this) {
6215            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6216            mProcessLimitOverride = max;
6217        }
6218        trimApplications();
6219    }
6220
6221    @Override
6222    public int getProcessLimit() {
6223        synchronized (this) {
6224            return mProcessLimitOverride;
6225        }
6226    }
6227
6228    void foregroundTokenDied(ForegroundToken token) {
6229        synchronized (ActivityManagerService.this) {
6230            synchronized (mPidsSelfLocked) {
6231                ForegroundToken cur
6232                    = mForegroundProcesses.get(token.pid);
6233                if (cur != token) {
6234                    return;
6235                }
6236                mForegroundProcesses.remove(token.pid);
6237                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6238                if (pr == null) {
6239                    return;
6240                }
6241                pr.forcingToForeground = null;
6242                updateProcessForegroundLocked(pr, false, false);
6243            }
6244            updateOomAdjLocked();
6245        }
6246    }
6247
6248    @Override
6249    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6250        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6251                "setProcessForeground()");
6252        synchronized(this) {
6253            boolean changed = false;
6254
6255            synchronized (mPidsSelfLocked) {
6256                ProcessRecord pr = mPidsSelfLocked.get(pid);
6257                if (pr == null && isForeground) {
6258                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6259                    return;
6260                }
6261                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6262                if (oldToken != null) {
6263                    oldToken.token.unlinkToDeath(oldToken, 0);
6264                    mForegroundProcesses.remove(pid);
6265                    if (pr != null) {
6266                        pr.forcingToForeground = null;
6267                    }
6268                    changed = true;
6269                }
6270                if (isForeground && token != null) {
6271                    ForegroundToken newToken = new ForegroundToken() {
6272                        @Override
6273                        public void binderDied() {
6274                            foregroundTokenDied(this);
6275                        }
6276                    };
6277                    newToken.pid = pid;
6278                    newToken.token = token;
6279                    try {
6280                        token.linkToDeath(newToken, 0);
6281                        mForegroundProcesses.put(pid, newToken);
6282                        pr.forcingToForeground = token;
6283                        changed = true;
6284                    } catch (RemoteException e) {
6285                        // If the process died while doing this, we will later
6286                        // do the cleanup with the process death link.
6287                    }
6288                }
6289            }
6290
6291            if (changed) {
6292                updateOomAdjLocked();
6293            }
6294        }
6295    }
6296
6297    // =========================================================
6298    // PROCESS INFO
6299    // =========================================================
6300
6301    static class ProcessInfoService extends IProcessInfoService.Stub {
6302        final ActivityManagerService mActivityManagerService;
6303        ProcessInfoService(ActivityManagerService activityManagerService) {
6304            mActivityManagerService = activityManagerService;
6305        }
6306
6307        @Override
6308        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6309            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6310        }
6311    }
6312
6313    /**
6314     * For each PID in the given input array, write the current process state
6315     * for that process into the output array, or -1 to indicate that no
6316     * process with the given PID exists.
6317     */
6318    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6319        if (pids == null) {
6320            throw new NullPointerException("pids");
6321        } else if (states == null) {
6322            throw new NullPointerException("states");
6323        } else if (pids.length != states.length) {
6324            throw new IllegalArgumentException("input and output arrays have different lengths!");
6325        }
6326
6327        synchronized (mPidsSelfLocked) {
6328            for (int i = 0; i < pids.length; i++) {
6329                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6330                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6331                        pr.curProcState;
6332            }
6333        }
6334    }
6335
6336    // =========================================================
6337    // PERMISSIONS
6338    // =========================================================
6339
6340    static class PermissionController extends IPermissionController.Stub {
6341        ActivityManagerService mActivityManagerService;
6342        PermissionController(ActivityManagerService activityManagerService) {
6343            mActivityManagerService = activityManagerService;
6344        }
6345
6346        @Override
6347        public boolean checkPermission(String permission, int pid, int uid) {
6348            return mActivityManagerService.checkPermission(permission, pid,
6349                    uid) == PackageManager.PERMISSION_GRANTED;
6350        }
6351    }
6352
6353    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6354        @Override
6355        public int checkComponentPermission(String permission, int pid, int uid,
6356                int owningUid, boolean exported) {
6357            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6358                    owningUid, exported);
6359        }
6360
6361        @Override
6362        public Object getAMSLock() {
6363            return ActivityManagerService.this;
6364        }
6365    }
6366
6367    /**
6368     * This can be called with or without the global lock held.
6369     */
6370    int checkComponentPermission(String permission, int pid, int uid,
6371            int owningUid, boolean exported) {
6372        if (pid == MY_PID) {
6373            return PackageManager.PERMISSION_GRANTED;
6374        }
6375        return ActivityManager.checkComponentPermission(permission, uid,
6376                owningUid, exported);
6377    }
6378
6379    /**
6380     * As the only public entry point for permissions checking, this method
6381     * can enforce the semantic that requesting a check on a null global
6382     * permission is automatically denied.  (Internally a null permission
6383     * string is used when calling {@link #checkComponentPermission} in cases
6384     * when only uid-based security is needed.)
6385     *
6386     * This can be called with or without the global lock held.
6387     */
6388    @Override
6389    public int checkPermission(String permission, int pid, int uid) {
6390        if (permission == null) {
6391            return PackageManager.PERMISSION_DENIED;
6392        }
6393        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6394    }
6395
6396    @Override
6397    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6398        if (permission == null) {
6399            return PackageManager.PERMISSION_DENIED;
6400        }
6401
6402        // We might be performing an operation on behalf of an indirect binder
6403        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6404        // client identity accordingly before proceeding.
6405        Identity tlsIdentity = sCallerIdentity.get();
6406        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6407            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6408                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6409            uid = tlsIdentity.uid;
6410            pid = tlsIdentity.pid;
6411        }
6412
6413        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6414    }
6415
6416    /**
6417     * Binder IPC calls go through the public entry point.
6418     * This can be called with or without the global lock held.
6419     */
6420    int checkCallingPermission(String permission) {
6421        return checkPermission(permission,
6422                Binder.getCallingPid(),
6423                UserHandle.getAppId(Binder.getCallingUid()));
6424    }
6425
6426    /**
6427     * This can be called with or without the global lock held.
6428     */
6429    void enforceCallingPermission(String permission, String func) {
6430        if (checkCallingPermission(permission)
6431                == PackageManager.PERMISSION_GRANTED) {
6432            return;
6433        }
6434
6435        String msg = "Permission Denial: " + func + " from pid="
6436                + Binder.getCallingPid()
6437                + ", uid=" + Binder.getCallingUid()
6438                + " requires " + permission;
6439        Slog.w(TAG, msg);
6440        throw new SecurityException(msg);
6441    }
6442
6443    /**
6444     * Determine if UID is holding permissions required to access {@link Uri} in
6445     * the given {@link ProviderInfo}. Final permission checking is always done
6446     * in {@link ContentProvider}.
6447     */
6448    private final boolean checkHoldingPermissionsLocked(
6449            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6450        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6451                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6452        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6453            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6454                    != PERMISSION_GRANTED) {
6455                return false;
6456            }
6457        }
6458        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6459    }
6460
6461    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6462            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6463        if (pi.applicationInfo.uid == uid) {
6464            return true;
6465        } else if (!pi.exported) {
6466            return false;
6467        }
6468
6469        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6470        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6471        try {
6472            // check if target holds top-level <provider> permissions
6473            if (!readMet && pi.readPermission != null && considerUidPermissions
6474                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6475                readMet = true;
6476            }
6477            if (!writeMet && pi.writePermission != null && considerUidPermissions
6478                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6479                writeMet = true;
6480            }
6481
6482            // track if unprotected read/write is allowed; any denied
6483            // <path-permission> below removes this ability
6484            boolean allowDefaultRead = pi.readPermission == null;
6485            boolean allowDefaultWrite = pi.writePermission == null;
6486
6487            // check if target holds any <path-permission> that match uri
6488            final PathPermission[] pps = pi.pathPermissions;
6489            if (pps != null) {
6490                final String path = grantUri.uri.getPath();
6491                int i = pps.length;
6492                while (i > 0 && (!readMet || !writeMet)) {
6493                    i--;
6494                    PathPermission pp = pps[i];
6495                    if (pp.match(path)) {
6496                        if (!readMet) {
6497                            final String pprperm = pp.getReadPermission();
6498                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6499                                    + pprperm + " for " + pp.getPath()
6500                                    + ": match=" + pp.match(path)
6501                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6502                            if (pprperm != null) {
6503                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6504                                        == PERMISSION_GRANTED) {
6505                                    readMet = true;
6506                                } else {
6507                                    allowDefaultRead = false;
6508                                }
6509                            }
6510                        }
6511                        if (!writeMet) {
6512                            final String ppwperm = pp.getWritePermission();
6513                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6514                                    + ppwperm + " for " + pp.getPath()
6515                                    + ": match=" + pp.match(path)
6516                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6517                            if (ppwperm != null) {
6518                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6519                                        == PERMISSION_GRANTED) {
6520                                    writeMet = true;
6521                                } else {
6522                                    allowDefaultWrite = false;
6523                                }
6524                            }
6525                        }
6526                    }
6527                }
6528            }
6529
6530            // grant unprotected <provider> read/write, if not blocked by
6531            // <path-permission> above
6532            if (allowDefaultRead) readMet = true;
6533            if (allowDefaultWrite) writeMet = true;
6534
6535        } catch (RemoteException e) {
6536            return false;
6537        }
6538
6539        return readMet && writeMet;
6540    }
6541
6542    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6543        ProviderInfo pi = null;
6544        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6545        if (cpr != null) {
6546            pi = cpr.info;
6547        } else {
6548            try {
6549                pi = AppGlobals.getPackageManager().resolveContentProvider(
6550                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6551            } catch (RemoteException ex) {
6552            }
6553        }
6554        return pi;
6555    }
6556
6557    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6558        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6559        if (targetUris != null) {
6560            return targetUris.get(grantUri);
6561        }
6562        return null;
6563    }
6564
6565    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6566            String targetPkg, int targetUid, GrantUri grantUri) {
6567        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6568        if (targetUris == null) {
6569            targetUris = Maps.newArrayMap();
6570            mGrantedUriPermissions.put(targetUid, targetUris);
6571        }
6572
6573        UriPermission perm = targetUris.get(grantUri);
6574        if (perm == null) {
6575            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6576            targetUris.put(grantUri, perm);
6577        }
6578
6579        return perm;
6580    }
6581
6582    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6583            final int modeFlags) {
6584        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6585        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6586                : UriPermission.STRENGTH_OWNED;
6587
6588        // Root gets to do everything.
6589        if (uid == 0) {
6590            return true;
6591        }
6592
6593        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6594        if (perms == null) return false;
6595
6596        // First look for exact match
6597        final UriPermission exactPerm = perms.get(grantUri);
6598        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6599            return true;
6600        }
6601
6602        // No exact match, look for prefixes
6603        final int N = perms.size();
6604        for (int i = 0; i < N; i++) {
6605            final UriPermission perm = perms.valueAt(i);
6606            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6607                    && perm.getStrength(modeFlags) >= minStrength) {
6608                return true;
6609            }
6610        }
6611
6612        return false;
6613    }
6614
6615    /**
6616     * @param uri This uri must NOT contain an embedded userId.
6617     * @param userId The userId in which the uri is to be resolved.
6618     */
6619    @Override
6620    public int checkUriPermission(Uri uri, int pid, int uid,
6621            final int modeFlags, int userId, IBinder callerToken) {
6622        enforceNotIsolatedCaller("checkUriPermission");
6623
6624        // Another redirected-binder-call permissions check as in
6625        // {@link checkPermissionWithToken}.
6626        Identity tlsIdentity = sCallerIdentity.get();
6627        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6628            uid = tlsIdentity.uid;
6629            pid = tlsIdentity.pid;
6630        }
6631
6632        // Our own process gets to do everything.
6633        if (pid == MY_PID) {
6634            return PackageManager.PERMISSION_GRANTED;
6635        }
6636        synchronized (this) {
6637            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6638                    ? PackageManager.PERMISSION_GRANTED
6639                    : PackageManager.PERMISSION_DENIED;
6640        }
6641    }
6642
6643    /**
6644     * Check if the targetPkg can be granted permission to access uri by
6645     * the callingUid using the given modeFlags.  Throws a security exception
6646     * if callingUid is not allowed to do this.  Returns the uid of the target
6647     * if the URI permission grant should be performed; returns -1 if it is not
6648     * needed (for example targetPkg already has permission to access the URI).
6649     * If you already know the uid of the target, you can supply it in
6650     * lastTargetUid else set that to -1.
6651     */
6652    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6653            final int modeFlags, int lastTargetUid) {
6654        if (!Intent.isAccessUriMode(modeFlags)) {
6655            return -1;
6656        }
6657
6658        if (targetPkg != null) {
6659            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6660                    "Checking grant " + targetPkg + " permission to " + grantUri);
6661        }
6662
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664
6665        // If this is not a content: uri, we can't do anything with it.
6666        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6667            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6668                    "Can't grant URI permission for non-content URI: " + grantUri);
6669            return -1;
6670        }
6671
6672        final String authority = grantUri.uri.getAuthority();
6673        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6674        if (pi == null) {
6675            Slog.w(TAG, "No content provider found for permission check: " +
6676                    grantUri.uri.toSafeString());
6677            return -1;
6678        }
6679
6680        int targetUid = lastTargetUid;
6681        if (targetUid < 0 && targetPkg != null) {
6682            try {
6683                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6684                if (targetUid < 0) {
6685                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6686                            "Can't grant URI permission no uid for: " + targetPkg);
6687                    return -1;
6688                }
6689            } catch (RemoteException ex) {
6690                return -1;
6691            }
6692        }
6693
6694        if (targetUid >= 0) {
6695            // First...  does the target actually need this permission?
6696            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6697                // No need to grant the target this permission.
6698                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6699                        "Target " + targetPkg + " already has full permission to " + grantUri);
6700                return -1;
6701            }
6702        } else {
6703            // First...  there is no target package, so can anyone access it?
6704            boolean allowed = pi.exported;
6705            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6706                if (pi.readPermission != null) {
6707                    allowed = false;
6708                }
6709            }
6710            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6711                if (pi.writePermission != null) {
6712                    allowed = false;
6713                }
6714            }
6715            if (allowed) {
6716                return -1;
6717            }
6718        }
6719
6720        /* There is a special cross user grant if:
6721         * - The target is on another user.
6722         * - Apps on the current user can access the uri without any uid permissions.
6723         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6724         * grant uri permissions.
6725         */
6726        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6727                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6728                modeFlags, false /*without considering the uid permissions*/);
6729
6730        // Second...  is the provider allowing granting of URI permissions?
6731        if (!specialCrossUserGrant) {
6732            if (!pi.grantUriPermissions) {
6733                throw new SecurityException("Provider " + pi.packageName
6734                        + "/" + pi.name
6735                        + " does not allow granting of Uri permissions (uri "
6736                        + grantUri + ")");
6737            }
6738            if (pi.uriPermissionPatterns != null) {
6739                final int N = pi.uriPermissionPatterns.length;
6740                boolean allowed = false;
6741                for (int i=0; i<N; i++) {
6742                    if (pi.uriPermissionPatterns[i] != null
6743                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6744                        allowed = true;
6745                        break;
6746                    }
6747                }
6748                if (!allowed) {
6749                    throw new SecurityException("Provider " + pi.packageName
6750                            + "/" + pi.name
6751                            + " does not allow granting of permission to path of Uri "
6752                            + grantUri);
6753                }
6754            }
6755        }
6756
6757        // Third...  does the caller itself have permission to access
6758        // this uri?
6759        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6760            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6761                // Require they hold a strong enough Uri permission
6762                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6763                    throw new SecurityException("Uid " + callingUid
6764                            + " does not have permission to uri " + grantUri);
6765                }
6766            }
6767        }
6768        return targetUid;
6769    }
6770
6771    /**
6772     * @param uri This uri must NOT contain an embedded userId.
6773     * @param userId The userId in which the uri is to be resolved.
6774     */
6775    @Override
6776    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6777            final int modeFlags, int userId) {
6778        enforceNotIsolatedCaller("checkGrantUriPermission");
6779        synchronized(this) {
6780            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6781                    new GrantUri(userId, uri, false), modeFlags, -1);
6782        }
6783    }
6784
6785    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6786            final int modeFlags, UriPermissionOwner owner) {
6787        if (!Intent.isAccessUriMode(modeFlags)) {
6788            return;
6789        }
6790
6791        // So here we are: the caller has the assumed permission
6792        // to the uri, and the target doesn't.  Let's now give this to
6793        // the target.
6794
6795        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6796                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6797
6798        final String authority = grantUri.uri.getAuthority();
6799        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6800        if (pi == null) {
6801            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6802            return;
6803        }
6804
6805        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6806            grantUri.prefix = true;
6807        }
6808        final UriPermission perm = findOrCreateUriPermissionLocked(
6809                pi.packageName, targetPkg, targetUid, grantUri);
6810        perm.grantModes(modeFlags, owner);
6811    }
6812
6813    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6814            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6815        if (targetPkg == null) {
6816            throw new NullPointerException("targetPkg");
6817        }
6818        int targetUid;
6819        final IPackageManager pm = AppGlobals.getPackageManager();
6820        try {
6821            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6822        } catch (RemoteException ex) {
6823            return;
6824        }
6825
6826        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6827                targetUid);
6828        if (targetUid < 0) {
6829            return;
6830        }
6831
6832        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6833                owner);
6834    }
6835
6836    static class NeededUriGrants extends ArrayList<GrantUri> {
6837        final String targetPkg;
6838        final int targetUid;
6839        final int flags;
6840
6841        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6842            this.targetPkg = targetPkg;
6843            this.targetUid = targetUid;
6844            this.flags = flags;
6845        }
6846    }
6847
6848    /**
6849     * Like checkGrantUriPermissionLocked, but takes an Intent.
6850     */
6851    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6852            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6853        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6854                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6855                + " clip=" + (intent != null ? intent.getClipData() : null)
6856                + " from " + intent + "; flags=0x"
6857                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6858
6859        if (targetPkg == null) {
6860            throw new NullPointerException("targetPkg");
6861        }
6862
6863        if (intent == null) {
6864            return null;
6865        }
6866        Uri data = intent.getData();
6867        ClipData clip = intent.getClipData();
6868        if (data == null && clip == null) {
6869            return null;
6870        }
6871        // Default userId for uris in the intent (if they don't specify it themselves)
6872        int contentUserHint = intent.getContentUserHint();
6873        if (contentUserHint == UserHandle.USER_CURRENT) {
6874            contentUserHint = UserHandle.getUserId(callingUid);
6875        }
6876        final IPackageManager pm = AppGlobals.getPackageManager();
6877        int targetUid;
6878        if (needed != null) {
6879            targetUid = needed.targetUid;
6880        } else {
6881            try {
6882                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6883            } catch (RemoteException ex) {
6884                return null;
6885            }
6886            if (targetUid < 0) {
6887                if (DEBUG_URI_PERMISSION) {
6888                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6889                            + " on user " + targetUserId);
6890                }
6891                return null;
6892            }
6893        }
6894        if (data != null) {
6895            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6896            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6897                    targetUid);
6898            if (targetUid > 0) {
6899                if (needed == null) {
6900                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6901                }
6902                needed.add(grantUri);
6903            }
6904        }
6905        if (clip != null) {
6906            for (int i=0; i<clip.getItemCount(); i++) {
6907                Uri uri = clip.getItemAt(i).getUri();
6908                if (uri != null) {
6909                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6910                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6911                            targetUid);
6912                    if (targetUid > 0) {
6913                        if (needed == null) {
6914                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6915                        }
6916                        needed.add(grantUri);
6917                    }
6918                } else {
6919                    Intent clipIntent = clip.getItemAt(i).getIntent();
6920                    if (clipIntent != null) {
6921                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6922                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6923                        if (newNeeded != null) {
6924                            needed = newNeeded;
6925                        }
6926                    }
6927                }
6928            }
6929        }
6930
6931        return needed;
6932    }
6933
6934    /**
6935     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6936     */
6937    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6938            UriPermissionOwner owner) {
6939        if (needed != null) {
6940            for (int i=0; i<needed.size(); i++) {
6941                GrantUri grantUri = needed.get(i);
6942                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6943                        grantUri, needed.flags, owner);
6944            }
6945        }
6946    }
6947
6948    void grantUriPermissionFromIntentLocked(int callingUid,
6949            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6950        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6951                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6952        if (needed == null) {
6953            return;
6954        }
6955
6956        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6957    }
6958
6959    /**
6960     * @param uri This uri must NOT contain an embedded userId.
6961     * @param userId The userId in which the uri is to be resolved.
6962     */
6963    @Override
6964    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6965            final int modeFlags, int userId) {
6966        enforceNotIsolatedCaller("grantUriPermission");
6967        GrantUri grantUri = new GrantUri(userId, uri, false);
6968        synchronized(this) {
6969            final ProcessRecord r = getRecordForAppLocked(caller);
6970            if (r == null) {
6971                throw new SecurityException("Unable to find app for caller "
6972                        + caller
6973                        + " when granting permission to uri " + grantUri);
6974            }
6975            if (targetPkg == null) {
6976                throw new IllegalArgumentException("null target");
6977            }
6978            if (grantUri == null) {
6979                throw new IllegalArgumentException("null uri");
6980            }
6981
6982            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6983                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6984                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6985                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6986
6987            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6988                    UserHandle.getUserId(r.uid));
6989        }
6990    }
6991
6992    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6993        if (perm.modeFlags == 0) {
6994            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6995                    perm.targetUid);
6996            if (perms != null) {
6997                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6998                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6999
7000                perms.remove(perm.uri);
7001                if (perms.isEmpty()) {
7002                    mGrantedUriPermissions.remove(perm.targetUid);
7003                }
7004            }
7005        }
7006    }
7007
7008    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7009        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7010
7011        final IPackageManager pm = AppGlobals.getPackageManager();
7012        final String authority = grantUri.uri.getAuthority();
7013        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7014        if (pi == null) {
7015            Slog.w(TAG, "No content provider found for permission revoke: "
7016                    + grantUri.toSafeString());
7017            return;
7018        }
7019
7020        // Does the caller have this permission on the URI?
7021        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7022            // If they don't have direct access to the URI, then revoke any
7023            // ownerless URI permissions that have been granted to them.
7024            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7025            if (perms != null) {
7026                boolean persistChanged = false;
7027                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7028                    final UriPermission perm = it.next();
7029                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7030                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7031                        if (DEBUG_URI_PERMISSION)
7032                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7033                                    " permission to " + perm.uri);
7034                        persistChanged |= perm.revokeModes(
7035                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7036                        if (perm.modeFlags == 0) {
7037                            it.remove();
7038                        }
7039                    }
7040                }
7041                if (perms.isEmpty()) {
7042                    mGrantedUriPermissions.remove(callingUid);
7043                }
7044                if (persistChanged) {
7045                    schedulePersistUriGrants();
7046                }
7047            }
7048            return;
7049        }
7050
7051        boolean persistChanged = false;
7052
7053        // Go through all of the permissions and remove any that match.
7054        int N = mGrantedUriPermissions.size();
7055        for (int i = 0; i < N; i++) {
7056            final int targetUid = mGrantedUriPermissions.keyAt(i);
7057            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7058
7059            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7060                final UriPermission perm = it.next();
7061                if (perm.uri.sourceUserId == grantUri.sourceUserId
7062                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7063                    if (DEBUG_URI_PERMISSION)
7064                        Slog.v(TAG,
7065                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7066                    persistChanged |= perm.revokeModes(
7067                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7068                    if (perm.modeFlags == 0) {
7069                        it.remove();
7070                    }
7071                }
7072            }
7073
7074            if (perms.isEmpty()) {
7075                mGrantedUriPermissions.remove(targetUid);
7076                N--;
7077                i--;
7078            }
7079        }
7080
7081        if (persistChanged) {
7082            schedulePersistUriGrants();
7083        }
7084    }
7085
7086    /**
7087     * @param uri This uri must NOT contain an embedded userId.
7088     * @param userId The userId in which the uri is to be resolved.
7089     */
7090    @Override
7091    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7092            int userId) {
7093        enforceNotIsolatedCaller("revokeUriPermission");
7094        synchronized(this) {
7095            final ProcessRecord r = getRecordForAppLocked(caller);
7096            if (r == null) {
7097                throw new SecurityException("Unable to find app for caller "
7098                        + caller
7099                        + " when revoking permission to uri " + uri);
7100            }
7101            if (uri == null) {
7102                Slog.w(TAG, "revokeUriPermission: null uri");
7103                return;
7104            }
7105
7106            if (!Intent.isAccessUriMode(modeFlags)) {
7107                return;
7108            }
7109
7110            final String authority = uri.getAuthority();
7111            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7112            if (pi == null) {
7113                Slog.w(TAG, "No content provider found for permission revoke: "
7114                        + uri.toSafeString());
7115                return;
7116            }
7117
7118            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7119        }
7120    }
7121
7122    /**
7123     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7124     * given package.
7125     *
7126     * @param packageName Package name to match, or {@code null} to apply to all
7127     *            packages.
7128     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7129     *            to all users.
7130     * @param persistable If persistable grants should be removed.
7131     */
7132    private void removeUriPermissionsForPackageLocked(
7133            String packageName, int userHandle, boolean persistable) {
7134        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7135            throw new IllegalArgumentException("Must narrow by either package or user");
7136        }
7137
7138        boolean persistChanged = false;
7139
7140        int N = mGrantedUriPermissions.size();
7141        for (int i = 0; i < N; i++) {
7142            final int targetUid = mGrantedUriPermissions.keyAt(i);
7143            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7144
7145            // Only inspect grants matching user
7146            if (userHandle == UserHandle.USER_ALL
7147                    || userHandle == UserHandle.getUserId(targetUid)) {
7148                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7149                    final UriPermission perm = it.next();
7150
7151                    // Only inspect grants matching package
7152                    if (packageName == null || perm.sourcePkg.equals(packageName)
7153                            || perm.targetPkg.equals(packageName)) {
7154                        persistChanged |= perm.revokeModes(persistable
7155                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7156
7157                        // Only remove when no modes remain; any persisted grants
7158                        // will keep this alive.
7159                        if (perm.modeFlags == 0) {
7160                            it.remove();
7161                        }
7162                    }
7163                }
7164
7165                if (perms.isEmpty()) {
7166                    mGrantedUriPermissions.remove(targetUid);
7167                    N--;
7168                    i--;
7169                }
7170            }
7171        }
7172
7173        if (persistChanged) {
7174            schedulePersistUriGrants();
7175        }
7176    }
7177
7178    @Override
7179    public IBinder newUriPermissionOwner(String name) {
7180        enforceNotIsolatedCaller("newUriPermissionOwner");
7181        synchronized(this) {
7182            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7183            return owner.getExternalTokenLocked();
7184        }
7185    }
7186
7187    /**
7188     * @param uri This uri must NOT contain an embedded userId.
7189     * @param sourceUserId The userId in which the uri is to be resolved.
7190     * @param targetUserId The userId of the app that receives the grant.
7191     */
7192    @Override
7193    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7194            final int modeFlags, int sourceUserId, int targetUserId) {
7195        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7196                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7197        synchronized(this) {
7198            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7199            if (owner == null) {
7200                throw new IllegalArgumentException("Unknown owner: " + token);
7201            }
7202            if (fromUid != Binder.getCallingUid()) {
7203                if (Binder.getCallingUid() != Process.myUid()) {
7204                    // Only system code can grant URI permissions on behalf
7205                    // of other users.
7206                    throw new SecurityException("nice try");
7207                }
7208            }
7209            if (targetPkg == null) {
7210                throw new IllegalArgumentException("null target");
7211            }
7212            if (uri == null) {
7213                throw new IllegalArgumentException("null uri");
7214            }
7215
7216            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7217                    modeFlags, owner, targetUserId);
7218        }
7219    }
7220
7221    /**
7222     * @param uri This uri must NOT contain an embedded userId.
7223     * @param userId The userId in which the uri is to be resolved.
7224     */
7225    @Override
7226    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7227        synchronized(this) {
7228            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7229            if (owner == null) {
7230                throw new IllegalArgumentException("Unknown owner: " + token);
7231            }
7232
7233            if (uri == null) {
7234                owner.removeUriPermissionsLocked(mode);
7235            } else {
7236                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7237            }
7238        }
7239    }
7240
7241    private void schedulePersistUriGrants() {
7242        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7243            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7244                    10 * DateUtils.SECOND_IN_MILLIS);
7245        }
7246    }
7247
7248    private void writeGrantedUriPermissions() {
7249        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7250
7251        // Snapshot permissions so we can persist without lock
7252        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7253        synchronized (this) {
7254            final int size = mGrantedUriPermissions.size();
7255            for (int i = 0; i < size; i++) {
7256                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7257                for (UriPermission perm : perms.values()) {
7258                    if (perm.persistedModeFlags != 0) {
7259                        persist.add(perm.snapshot());
7260                    }
7261                }
7262            }
7263        }
7264
7265        FileOutputStream fos = null;
7266        try {
7267            fos = mGrantFile.startWrite();
7268
7269            XmlSerializer out = new FastXmlSerializer();
7270            out.setOutput(fos, "utf-8");
7271            out.startDocument(null, true);
7272            out.startTag(null, TAG_URI_GRANTS);
7273            for (UriPermission.Snapshot perm : persist) {
7274                out.startTag(null, TAG_URI_GRANT);
7275                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7276                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7277                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7278                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7279                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7280                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7281                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7282                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7283                out.endTag(null, TAG_URI_GRANT);
7284            }
7285            out.endTag(null, TAG_URI_GRANTS);
7286            out.endDocument();
7287
7288            mGrantFile.finishWrite(fos);
7289        } catch (IOException e) {
7290            if (fos != null) {
7291                mGrantFile.failWrite(fos);
7292            }
7293        }
7294    }
7295
7296    private void readGrantedUriPermissionsLocked() {
7297        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7298
7299        final long now = System.currentTimeMillis();
7300
7301        FileInputStream fis = null;
7302        try {
7303            fis = mGrantFile.openRead();
7304            final XmlPullParser in = Xml.newPullParser();
7305            in.setInput(fis, null);
7306
7307            int type;
7308            while ((type = in.next()) != END_DOCUMENT) {
7309                final String tag = in.getName();
7310                if (type == START_TAG) {
7311                    if (TAG_URI_GRANT.equals(tag)) {
7312                        final int sourceUserId;
7313                        final int targetUserId;
7314                        final int userHandle = readIntAttribute(in,
7315                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7316                        if (userHandle != UserHandle.USER_NULL) {
7317                            // For backwards compatibility.
7318                            sourceUserId = userHandle;
7319                            targetUserId = userHandle;
7320                        } else {
7321                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7322                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7323                        }
7324                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7325                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7326                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7327                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7328                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7329                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7330
7331                        // Sanity check that provider still belongs to source package
7332                        final ProviderInfo pi = getProviderInfoLocked(
7333                                uri.getAuthority(), sourceUserId);
7334                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7335                            int targetUid = -1;
7336                            try {
7337                                targetUid = AppGlobals.getPackageManager()
7338                                        .getPackageUid(targetPkg, targetUserId);
7339                            } catch (RemoteException e) {
7340                            }
7341                            if (targetUid != -1) {
7342                                final UriPermission perm = findOrCreateUriPermissionLocked(
7343                                        sourcePkg, targetPkg, targetUid,
7344                                        new GrantUri(sourceUserId, uri, prefix));
7345                                perm.initPersistedModes(modeFlags, createdTime);
7346                            }
7347                        } else {
7348                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7349                                    + " but instead found " + pi);
7350                        }
7351                    }
7352                }
7353            }
7354        } catch (FileNotFoundException e) {
7355            // Missing grants is okay
7356        } catch (IOException e) {
7357            Slog.wtf(TAG, "Failed reading Uri grants", e);
7358        } catch (XmlPullParserException e) {
7359            Slog.wtf(TAG, "Failed reading Uri grants", e);
7360        } finally {
7361            IoUtils.closeQuietly(fis);
7362        }
7363    }
7364
7365    /**
7366     * @param uri This uri must NOT contain an embedded userId.
7367     * @param userId The userId in which the uri is to be resolved.
7368     */
7369    @Override
7370    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7371        enforceNotIsolatedCaller("takePersistableUriPermission");
7372
7373        Preconditions.checkFlagsArgument(modeFlags,
7374                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7375
7376        synchronized (this) {
7377            final int callingUid = Binder.getCallingUid();
7378            boolean persistChanged = false;
7379            GrantUri grantUri = new GrantUri(userId, uri, false);
7380
7381            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7382                    new GrantUri(userId, uri, false));
7383            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7384                    new GrantUri(userId, uri, true));
7385
7386            final boolean exactValid = (exactPerm != null)
7387                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7388            final boolean prefixValid = (prefixPerm != null)
7389                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7390
7391            if (!(exactValid || prefixValid)) {
7392                throw new SecurityException("No persistable permission grants found for UID "
7393                        + callingUid + " and Uri " + grantUri.toSafeString());
7394            }
7395
7396            if (exactValid) {
7397                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7398            }
7399            if (prefixValid) {
7400                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7401            }
7402
7403            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7404
7405            if (persistChanged) {
7406                schedulePersistUriGrants();
7407            }
7408        }
7409    }
7410
7411    /**
7412     * @param uri This uri must NOT contain an embedded userId.
7413     * @param userId The userId in which the uri is to be resolved.
7414     */
7415    @Override
7416    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7417        enforceNotIsolatedCaller("releasePersistableUriPermission");
7418
7419        Preconditions.checkFlagsArgument(modeFlags,
7420                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7421
7422        synchronized (this) {
7423            final int callingUid = Binder.getCallingUid();
7424            boolean persistChanged = false;
7425
7426            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7427                    new GrantUri(userId, uri, false));
7428            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7429                    new GrantUri(userId, uri, true));
7430            if (exactPerm == null && prefixPerm == null) {
7431                throw new SecurityException("No permission grants found for UID " + callingUid
7432                        + " and Uri " + uri.toSafeString());
7433            }
7434
7435            if (exactPerm != null) {
7436                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7437                removeUriPermissionIfNeededLocked(exactPerm);
7438            }
7439            if (prefixPerm != null) {
7440                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7441                removeUriPermissionIfNeededLocked(prefixPerm);
7442            }
7443
7444            if (persistChanged) {
7445                schedulePersistUriGrants();
7446            }
7447        }
7448    }
7449
7450    /**
7451     * Prune any older {@link UriPermission} for the given UID until outstanding
7452     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7453     *
7454     * @return if any mutations occured that require persisting.
7455     */
7456    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7457        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7458        if (perms == null) return false;
7459        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7460
7461        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7462        for (UriPermission perm : perms.values()) {
7463            if (perm.persistedModeFlags != 0) {
7464                persisted.add(perm);
7465            }
7466        }
7467
7468        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7469        if (trimCount <= 0) return false;
7470
7471        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7472        for (int i = 0; i < trimCount; i++) {
7473            final UriPermission perm = persisted.get(i);
7474
7475            if (DEBUG_URI_PERMISSION) {
7476                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7477            }
7478
7479            perm.releasePersistableModes(~0);
7480            removeUriPermissionIfNeededLocked(perm);
7481        }
7482
7483        return true;
7484    }
7485
7486    @Override
7487    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7488            String packageName, boolean incoming) {
7489        enforceNotIsolatedCaller("getPersistedUriPermissions");
7490        Preconditions.checkNotNull(packageName, "packageName");
7491
7492        final int callingUid = Binder.getCallingUid();
7493        final IPackageManager pm = AppGlobals.getPackageManager();
7494        try {
7495            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7496            if (packageUid != callingUid) {
7497                throw new SecurityException(
7498                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7499            }
7500        } catch (RemoteException e) {
7501            throw new SecurityException("Failed to verify package name ownership");
7502        }
7503
7504        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7505        synchronized (this) {
7506            if (incoming) {
7507                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7508                        callingUid);
7509                if (perms == null) {
7510                    Slog.w(TAG, "No permission grants found for " + packageName);
7511                } else {
7512                    for (UriPermission perm : perms.values()) {
7513                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7514                            result.add(perm.buildPersistedPublicApiObject());
7515                        }
7516                    }
7517                }
7518            } else {
7519                final int size = mGrantedUriPermissions.size();
7520                for (int i = 0; i < size; i++) {
7521                    final ArrayMap<GrantUri, UriPermission> perms =
7522                            mGrantedUriPermissions.valueAt(i);
7523                    for (UriPermission perm : perms.values()) {
7524                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7525                            result.add(perm.buildPersistedPublicApiObject());
7526                        }
7527                    }
7528                }
7529            }
7530        }
7531        return new ParceledListSlice<android.content.UriPermission>(result);
7532    }
7533
7534    @Override
7535    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7536        synchronized (this) {
7537            ProcessRecord app =
7538                who != null ? getRecordForAppLocked(who) : null;
7539            if (app == null) return;
7540
7541            Message msg = Message.obtain();
7542            msg.what = WAIT_FOR_DEBUGGER_MSG;
7543            msg.obj = app;
7544            msg.arg1 = waiting ? 1 : 0;
7545            mHandler.sendMessage(msg);
7546        }
7547    }
7548
7549    @Override
7550    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7551        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7552        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7553        outInfo.availMem = Process.getFreeMemory();
7554        outInfo.totalMem = Process.getTotalMemory();
7555        outInfo.threshold = homeAppMem;
7556        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7557        outInfo.hiddenAppThreshold = cachedAppMem;
7558        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7559                ProcessList.SERVICE_ADJ);
7560        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7561                ProcessList.VISIBLE_APP_ADJ);
7562        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7563                ProcessList.FOREGROUND_APP_ADJ);
7564    }
7565
7566    // =========================================================
7567    // TASK MANAGEMENT
7568    // =========================================================
7569
7570    @Override
7571    public List<IAppTask> getAppTasks(String callingPackage) {
7572        int callingUid = Binder.getCallingUid();
7573        long ident = Binder.clearCallingIdentity();
7574
7575        synchronized(this) {
7576            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7577            try {
7578                if (localLOGV) Slog.v(TAG, "getAppTasks");
7579
7580                final int N = mRecentTasks.size();
7581                for (int i = 0; i < N; i++) {
7582                    TaskRecord tr = mRecentTasks.get(i);
7583                    // Skip tasks that do not match the caller.  We don't need to verify
7584                    // callingPackage, because we are also limiting to callingUid and know
7585                    // that will limit to the correct security sandbox.
7586                    if (tr.effectiveUid != callingUid) {
7587                        continue;
7588                    }
7589                    Intent intent = tr.getBaseIntent();
7590                    if (intent == null ||
7591                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7592                        continue;
7593                    }
7594                    ActivityManager.RecentTaskInfo taskInfo =
7595                            createRecentTaskInfoFromTaskRecord(tr);
7596                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7597                    list.add(taskImpl);
7598                }
7599            } finally {
7600                Binder.restoreCallingIdentity(ident);
7601            }
7602            return list;
7603        }
7604    }
7605
7606    @Override
7607    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7608        final int callingUid = Binder.getCallingUid();
7609        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7610
7611        synchronized(this) {
7612            if (localLOGV) Slog.v(
7613                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7614
7615            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7616                    callingUid);
7617
7618            // TODO: Improve with MRU list from all ActivityStacks.
7619            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7620        }
7621
7622        return list;
7623    }
7624
7625    /**
7626     * Creates a new RecentTaskInfo from a TaskRecord.
7627     */
7628    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7629        // Update the task description to reflect any changes in the task stack
7630        tr.updateTaskDescription();
7631
7632        // Compose the recent task info
7633        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7634        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7635        rti.persistentId = tr.taskId;
7636        rti.baseIntent = new Intent(tr.getBaseIntent());
7637        rti.origActivity = tr.origActivity;
7638        rti.description = tr.lastDescription;
7639        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7640        rti.userId = tr.userId;
7641        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7642        rti.firstActiveTime = tr.firstActiveTime;
7643        rti.lastActiveTime = tr.lastActiveTime;
7644        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7645        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7646        return rti;
7647    }
7648
7649    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7650        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7651                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7652        if (!allowed) {
7653            if (checkPermission(android.Manifest.permission.GET_TASKS,
7654                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7655                // Temporary compatibility: some existing apps on the system image may
7656                // still be requesting the old permission and not switched to the new
7657                // one; if so, we'll still allow them full access.  This means we need
7658                // to see if they are holding the old permission and are a system app.
7659                try {
7660                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7661                        allowed = true;
7662                        Slog.w(TAG, caller + ": caller " + callingUid
7663                                + " is using old GET_TASKS but privileged; allowing");
7664                    }
7665                } catch (RemoteException e) {
7666                }
7667            }
7668        }
7669        if (!allowed) {
7670            Slog.w(TAG, caller + ": caller " + callingUid
7671                    + " does not hold GET_TASKS; limiting output");
7672        }
7673        return allowed;
7674    }
7675
7676    @Override
7677    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7678        final int callingUid = Binder.getCallingUid();
7679        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7680                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7681
7682        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7683        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7684        synchronized (this) {
7685            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7686                    callingUid);
7687            final boolean detailed = checkCallingPermission(
7688                    android.Manifest.permission.GET_DETAILED_TASKS)
7689                    == PackageManager.PERMISSION_GRANTED;
7690
7691            final int N = mRecentTasks.size();
7692            ArrayList<ActivityManager.RecentTaskInfo> res
7693                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7694                            maxNum < N ? maxNum : N);
7695
7696            final Set<Integer> includedUsers;
7697            if (includeProfiles) {
7698                includedUsers = getProfileIdsLocked(userId);
7699            } else {
7700                includedUsers = new HashSet<Integer>();
7701            }
7702            includedUsers.add(Integer.valueOf(userId));
7703
7704            for (int i=0; i<N && maxNum > 0; i++) {
7705                TaskRecord tr = mRecentTasks.get(i);
7706                // Only add calling user or related users recent tasks
7707                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7708                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7709                    continue;
7710                }
7711
7712                // Return the entry if desired by the caller.  We always return
7713                // the first entry, because callers always expect this to be the
7714                // foreground app.  We may filter others if the caller has
7715                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7716                // we should exclude the entry.
7717
7718                if (i == 0
7719                        || withExcluded
7720                        || (tr.intent == null)
7721                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7722                                == 0)) {
7723                    if (!allowed) {
7724                        // If the caller doesn't have the GET_TASKS permission, then only
7725                        // allow them to see a small subset of tasks -- their own and home.
7726                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7727                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7728                            continue;
7729                        }
7730                    }
7731                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7732                        if (tr.stack != null && tr.stack.isHomeStack()) {
7733                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7734                            continue;
7735                        }
7736                    }
7737                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7738                        // Don't include auto remove tasks that are finished or finishing.
7739                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7740                                + tr);
7741                        continue;
7742                    }
7743                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7744                            && !tr.isAvailable) {
7745                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
7746                        continue;
7747                    }
7748
7749                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7750                    if (!detailed) {
7751                        rti.baseIntent.replaceExtras((Bundle)null);
7752                    }
7753
7754                    res.add(rti);
7755                    maxNum--;
7756                }
7757            }
7758            return res;
7759        }
7760    }
7761
7762    @Override
7763    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7764        synchronized (this) {
7765            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7766                    "getTaskThumbnail()");
7767            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
7768            if (tr != null) {
7769                return tr.getTaskThumbnailLocked();
7770            }
7771        }
7772        return null;
7773    }
7774
7775    @Override
7776    public int addAppTask(IBinder activityToken, Intent intent,
7777            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7778        final int callingUid = Binder.getCallingUid();
7779        final long callingIdent = Binder.clearCallingIdentity();
7780
7781        try {
7782            synchronized (this) {
7783                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7784                if (r == null) {
7785                    throw new IllegalArgumentException("Activity does not exist; token="
7786                            + activityToken);
7787                }
7788                ComponentName comp = intent.getComponent();
7789                if (comp == null) {
7790                    throw new IllegalArgumentException("Intent " + intent
7791                            + " must specify explicit component");
7792                }
7793                if (thumbnail.getWidth() != mThumbnailWidth
7794                        || thumbnail.getHeight() != mThumbnailHeight) {
7795                    throw new IllegalArgumentException("Bad thumbnail size: got "
7796                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7797                            + mThumbnailWidth + "x" + mThumbnailHeight);
7798                }
7799                if (intent.getSelector() != null) {
7800                    intent.setSelector(null);
7801                }
7802                if (intent.getSourceBounds() != null) {
7803                    intent.setSourceBounds(null);
7804                }
7805                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7806                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7807                        // The caller has added this as an auto-remove task...  that makes no
7808                        // sense, so turn off auto-remove.
7809                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7810                    }
7811                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7812                    // Must be a new task.
7813                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7814                }
7815                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7816                    mLastAddedTaskActivity = null;
7817                }
7818                ActivityInfo ainfo = mLastAddedTaskActivity;
7819                if (ainfo == null) {
7820                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7821                            comp, 0, UserHandle.getUserId(callingUid));
7822                    if (ainfo.applicationInfo.uid != callingUid) {
7823                        throw new SecurityException(
7824                                "Can't add task for another application: target uid="
7825                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7826                    }
7827                }
7828
7829                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7830                        intent, description);
7831
7832                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7833                if (trimIdx >= 0) {
7834                    // If this would have caused a trim, then we'll abort because that
7835                    // means it would be added at the end of the list but then just removed.
7836                    return INVALID_TASK_ID;
7837                }
7838
7839                final int N = mRecentTasks.size();
7840                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
7841                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7842                    tr.removedFromRecents();
7843                }
7844
7845                task.inRecents = true;
7846                mRecentTasks.add(task);
7847                r.task.stack.addTask(task, false, false);
7848
7849                task.setLastThumbnail(thumbnail);
7850                task.freeLastThumbnail();
7851
7852                return task.taskId;
7853            }
7854        } finally {
7855            Binder.restoreCallingIdentity(callingIdent);
7856        }
7857    }
7858
7859    @Override
7860    public Point getAppTaskThumbnailSize() {
7861        synchronized (this) {
7862            return new Point(mThumbnailWidth,  mThumbnailHeight);
7863        }
7864    }
7865
7866    @Override
7867    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7868        synchronized (this) {
7869            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7870            if (r != null) {
7871                r.setTaskDescription(td);
7872                r.task.updateTaskDescription();
7873            }
7874        }
7875    }
7876
7877    @Override
7878    public void setTaskResizeable(int taskId, boolean resizeable) {
7879        synchronized (this) {
7880            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7881            if (task == null) {
7882                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
7883                return;
7884            }
7885            if (task.mResizeable != resizeable) {
7886                task.mResizeable = resizeable;
7887                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
7888                mStackSupervisor.resumeTopActivitiesLocked();
7889            }
7890        }
7891    }
7892
7893    @Override
7894    public Bitmap getTaskDescriptionIcon(String filename) {
7895        if (!FileUtils.isValidExtFilename(filename)
7896                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
7897            throw new IllegalArgumentException("Bad filename: " + filename);
7898        }
7899        return mTaskPersister.getTaskDescriptionIcon(filename);
7900    }
7901
7902    @Override
7903    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
7904            throws RemoteException {
7905        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
7906                opts.getCustomInPlaceResId() == 0) {
7907            throw new IllegalArgumentException("Expected in-place ActivityOption " +
7908                    "with valid animation");
7909        }
7910        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
7911        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
7912                opts.getCustomInPlaceResId());
7913        mWindowManager.executeAppTransition();
7914    }
7915
7916    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
7917        mRecentTasks.remove(tr);
7918        tr.removedFromRecents();
7919        ComponentName component = tr.getBaseIntent().getComponent();
7920        if (component == null) {
7921            Slog.w(TAG, "No component for base intent of task: " + tr);
7922            return;
7923        }
7924
7925        if (!killProcess) {
7926            return;
7927        }
7928
7929        // Determine if the process(es) for this task should be killed.
7930        final String pkg = component.getPackageName();
7931        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
7932        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7933        for (int i = 0; i < pmap.size(); i++) {
7934
7935            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7936            for (int j = 0; j < uids.size(); j++) {
7937                ProcessRecord proc = uids.valueAt(j);
7938                if (proc.userId != tr.userId) {
7939                    // Don't kill process for a different user.
7940                    continue;
7941                }
7942                if (proc == mHomeProcess) {
7943                    // Don't kill the home process along with tasks from the same package.
7944                    continue;
7945                }
7946                if (!proc.pkgList.containsKey(pkg)) {
7947                    // Don't kill process that is not associated with this task.
7948                    continue;
7949                }
7950
7951                for (int k = 0; k < proc.activities.size(); k++) {
7952                    TaskRecord otherTask = proc.activities.get(k).task;
7953                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
7954                        // Don't kill process(es) that has an activity in a different task that is
7955                        // also in recents.
7956                        return;
7957                    }
7958                }
7959
7960                // Add process to kill list.
7961                procsToKill.add(proc);
7962            }
7963        }
7964
7965        // Find any running services associated with this app and stop if needed.
7966        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
7967
7968        // Kill the running processes.
7969        for (int i = 0; i < procsToKill.size(); i++) {
7970            ProcessRecord pr = procsToKill.get(i);
7971            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7972                pr.kill("remove task", true);
7973            } else {
7974                pr.waitingToKill = "remove task";
7975            }
7976        }
7977    }
7978
7979    private void removeTasksByPackageNameLocked(String packageName, int userId) {
7980        // Remove all tasks with activities in the specified package from the list of recent tasks
7981        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7982            TaskRecord tr = mRecentTasks.get(i);
7983            if (tr.userId != userId) continue;
7984
7985            ComponentName cn = tr.intent.getComponent();
7986            if (cn != null && cn.getPackageName().equals(packageName)) {
7987                // If the package name matches, remove the task.
7988                removeTaskByIdLocked(tr.taskId, true);
7989            }
7990        }
7991    }
7992
7993    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
7994        final IPackageManager pm = AppGlobals.getPackageManager();
7995        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
7996
7997        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7998            TaskRecord tr = mRecentTasks.get(i);
7999            if (tr.userId != userId) continue;
8000
8001            ComponentName cn = tr.intent.getComponent();
8002            if (cn != null && cn.getPackageName().equals(packageName)) {
8003                // Skip if component still exists in the package.
8004                if (componentsKnownToExist.contains(cn)) continue;
8005
8006                try {
8007                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8008                    if (info != null) {
8009                        componentsKnownToExist.add(cn);
8010                    } else {
8011                        removeTaskByIdLocked(tr.taskId, false);
8012                    }
8013                } catch (RemoteException e) {
8014                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8015                }
8016            }
8017        }
8018    }
8019
8020    /**
8021     * Removes the task with the specified task id.
8022     *
8023     * @param taskId Identifier of the task to be removed.
8024     * @param killProcess Kill any process associated with the task if possible.
8025     * @return Returns true if the given task was found and removed.
8026     */
8027    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8028        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8029        if (tr != null) {
8030            tr.removeTaskActivitiesLocked();
8031            cleanUpRemovedTaskLocked(tr, killProcess);
8032            if (tr.isPersistable) {
8033                notifyTaskPersisterLocked(null, true);
8034            }
8035            return true;
8036        }
8037        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8038        return false;
8039    }
8040
8041    @Override
8042    public boolean removeTask(int taskId) {
8043        synchronized (this) {
8044            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8045                    "removeTask()");
8046            long ident = Binder.clearCallingIdentity();
8047            try {
8048                return removeTaskByIdLocked(taskId, true);
8049            } finally {
8050                Binder.restoreCallingIdentity(ident);
8051            }
8052        }
8053    }
8054
8055    /**
8056     * TODO: Add mController hook
8057     */
8058    @Override
8059    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8060        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8061                "moveTaskToFront()");
8062
8063        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8064        synchronized(this) {
8065            moveTaskToFrontLocked(taskId, flags, options);
8066        }
8067    }
8068
8069    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8070        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8071                Binder.getCallingUid(), -1, -1, "Task to front")) {
8072            ActivityOptions.abort(options);
8073            return;
8074        }
8075        final long origId = Binder.clearCallingIdentity();
8076        try {
8077            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8078            if (task == null) {
8079                Slog.d(TAG, "Could not find task for id: "+ taskId);
8080                return;
8081            }
8082            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8083                mStackSupervisor.showLockTaskToast();
8084                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8085                return;
8086            }
8087            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8088            if (prev != null && prev.isRecentsActivity()) {
8089                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8090            }
8091            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8092        } finally {
8093            Binder.restoreCallingIdentity(origId);
8094        }
8095        ActivityOptions.abort(options);
8096    }
8097
8098    /**
8099     * Moves an activity, and all of the other activities within the same task, to the bottom
8100     * of the history stack.  The activity's order within the task is unchanged.
8101     *
8102     * @param token A reference to the activity we wish to move
8103     * @param nonRoot If false then this only works if the activity is the root
8104     *                of a task; if true it will work for any activity in a task.
8105     * @return Returns true if the move completed, false if not.
8106     */
8107    @Override
8108    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8109        enforceNotIsolatedCaller("moveActivityTaskToBack");
8110        synchronized(this) {
8111            final long origId = Binder.clearCallingIdentity();
8112            try {
8113                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8114                if (taskId >= 0) {
8115                    if ((mStackSupervisor.mLockTaskModeTask != null)
8116                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8117                        mStackSupervisor.showLockTaskToast();
8118                        return false;
8119                    }
8120                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8121                }
8122            } finally {
8123                Binder.restoreCallingIdentity(origId);
8124            }
8125        }
8126        return false;
8127    }
8128
8129    @Override
8130    public void moveTaskBackwards(int task) {
8131        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8132                "moveTaskBackwards()");
8133
8134        synchronized(this) {
8135            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8136                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8137                return;
8138            }
8139            final long origId = Binder.clearCallingIdentity();
8140            moveTaskBackwardsLocked(task);
8141            Binder.restoreCallingIdentity(origId);
8142        }
8143    }
8144
8145    private final void moveTaskBackwardsLocked(int task) {
8146        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8147    }
8148
8149    @Override
8150    public IBinder getHomeActivityToken() throws RemoteException {
8151        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8152                "getHomeActivityToken()");
8153        synchronized (this) {
8154            return mStackSupervisor.getHomeActivityToken();
8155        }
8156    }
8157
8158    @Override
8159    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8160            IActivityContainerCallback callback) throws RemoteException {
8161        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8162                "createActivityContainer()");
8163        synchronized (this) {
8164            if (parentActivityToken == null) {
8165                throw new IllegalArgumentException("parent token must not be null");
8166            }
8167            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8168            if (r == null) {
8169                return null;
8170            }
8171            if (callback == null) {
8172                throw new IllegalArgumentException("callback must not be null");
8173            }
8174            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8175        }
8176    }
8177
8178    @Override
8179    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8180        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8181                "deleteActivityContainer()");
8182        synchronized (this) {
8183            mStackSupervisor.deleteActivityContainer(container);
8184        }
8185    }
8186
8187    @Override
8188    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8189        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8190                "createStackOnDisplay()");
8191        synchronized (this) {
8192            final int stackId = mStackSupervisor.getNextStackId();
8193            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8194            if (stack == null) {
8195                return null;
8196            }
8197            return stack.mActivityContainer;
8198        }
8199    }
8200
8201    @Override
8202    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8203            throws RemoteException {
8204        synchronized (this) {
8205            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8206            if (stack != null) {
8207                return stack.mActivityContainer;
8208            }
8209            return null;
8210        }
8211    }
8212
8213    @Override
8214    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8215        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8216                "moveTaskToStack()");
8217        if (stackId == HOME_STACK_ID) {
8218            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8219                    new RuntimeException("here").fillInStackTrace());
8220        }
8221        synchronized (this) {
8222            long ident = Binder.clearCallingIdentity();
8223            try {
8224                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8225                        + stackId + " toTop=" + toTop);
8226                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8227            } finally {
8228                Binder.restoreCallingIdentity(ident);
8229            }
8230        }
8231    }
8232
8233    @Override
8234    public void resizeStack(int stackId, Rect bounds) {
8235        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8236                "resizeStack()");
8237        long ident = Binder.clearCallingIdentity();
8238        try {
8239            synchronized (this) {
8240                mStackSupervisor.resizeStackLocked(stackId, bounds);
8241            }
8242        } finally {
8243            Binder.restoreCallingIdentity(ident);
8244        }
8245    }
8246
8247    @Override
8248    public List<StackInfo> getAllStackInfos() {
8249        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8250                "getAllStackInfos()");
8251        long ident = Binder.clearCallingIdentity();
8252        try {
8253            synchronized (this) {
8254                return mStackSupervisor.getAllStackInfosLocked();
8255            }
8256        } finally {
8257            Binder.restoreCallingIdentity(ident);
8258        }
8259    }
8260
8261    @Override
8262    public StackInfo getStackInfo(int stackId) {
8263        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8264                "getStackInfo()");
8265        long ident = Binder.clearCallingIdentity();
8266        try {
8267            synchronized (this) {
8268                return mStackSupervisor.getStackInfoLocked(stackId);
8269            }
8270        } finally {
8271            Binder.restoreCallingIdentity(ident);
8272        }
8273    }
8274
8275    @Override
8276    public boolean isInHomeStack(int taskId) {
8277        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8278                "getStackInfo()");
8279        long ident = Binder.clearCallingIdentity();
8280        try {
8281            synchronized (this) {
8282                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8283                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8284            }
8285        } finally {
8286            Binder.restoreCallingIdentity(ident);
8287        }
8288    }
8289
8290    @Override
8291    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8292        synchronized(this) {
8293            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8294        }
8295    }
8296
8297    private boolean isLockTaskAuthorized(String pkg) {
8298        final DevicePolicyManager dpm = (DevicePolicyManager)
8299                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8300        try {
8301            int uid = mContext.getPackageManager().getPackageUid(pkg,
8302                    Binder.getCallingUserHandle().getIdentifier());
8303            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8304        } catch (NameNotFoundException e) {
8305            return false;
8306        }
8307    }
8308
8309    void startLockTaskMode(TaskRecord task) {
8310        final String pkg;
8311        synchronized (this) {
8312            pkg = task.intent.getComponent().getPackageName();
8313        }
8314        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8315        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8316            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8317                    StatusBarManagerInternal.class);
8318            if (statusBarManager != null) {
8319                statusBarManager.showScreenPinningRequest();
8320            }
8321            return;
8322        }
8323        long ident = Binder.clearCallingIdentity();
8324        try {
8325            synchronized (this) {
8326                // Since we lost lock on task, make sure it is still there.
8327                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8328                if (task != null) {
8329                    if (!isSystemInitiated
8330                            && ((mStackSupervisor.getFocusedStack() == null)
8331                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8332                        throw new IllegalArgumentException("Invalid task, not in foreground");
8333                    }
8334                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8335                            "startLockTask");
8336                }
8337            }
8338        } finally {
8339            Binder.restoreCallingIdentity(ident);
8340        }
8341    }
8342
8343    @Override
8344    public void startLockTaskMode(int taskId) {
8345        final TaskRecord task;
8346        long ident = Binder.clearCallingIdentity();
8347        try {
8348            synchronized (this) {
8349                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8350            }
8351        } finally {
8352            Binder.restoreCallingIdentity(ident);
8353        }
8354        if (task != null) {
8355            startLockTaskMode(task);
8356        }
8357    }
8358
8359    @Override
8360    public void startLockTaskMode(IBinder token) {
8361        final TaskRecord task;
8362        long ident = Binder.clearCallingIdentity();
8363        try {
8364            synchronized (this) {
8365                final ActivityRecord r = ActivityRecord.forToken(token);
8366                if (r == null) {
8367                    return;
8368                }
8369                task = r.task;
8370            }
8371        } finally {
8372            Binder.restoreCallingIdentity(ident);
8373        }
8374        if (task != null) {
8375            startLockTaskMode(task);
8376        }
8377    }
8378
8379    @Override
8380    public void startLockTaskModeOnCurrent() throws RemoteException {
8381        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8382                "startLockTaskModeOnCurrent");
8383        long ident = Binder.clearCallingIdentity();
8384        try {
8385            ActivityRecord r = null;
8386            synchronized (this) {
8387                r = mStackSupervisor.topRunningActivityLocked();
8388            }
8389            startLockTaskMode(r.task);
8390        } finally {
8391            Binder.restoreCallingIdentity(ident);
8392        }
8393    }
8394
8395    @Override
8396    public void stopLockTaskMode() {
8397        // Verify that the user matches the package of the intent for the TaskRecord
8398        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8399        // and stopLockTaskMode.
8400        final int callingUid = Binder.getCallingUid();
8401        if (callingUid != Process.SYSTEM_UID) {
8402            try {
8403                String pkg =
8404                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8405                int uid = mContext.getPackageManager().getPackageUid(pkg,
8406                        Binder.getCallingUserHandle().getIdentifier());
8407                if (uid != callingUid) {
8408                    throw new SecurityException("Invalid uid, expected " + uid);
8409                }
8410            } catch (NameNotFoundException e) {
8411                Log.d(TAG, "stopLockTaskMode " + e);
8412                return;
8413            }
8414        }
8415        long ident = Binder.clearCallingIdentity();
8416        try {
8417            Log.d(TAG, "stopLockTaskMode");
8418            // Stop lock task
8419            synchronized (this) {
8420                mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8421            }
8422        } finally {
8423            Binder.restoreCallingIdentity(ident);
8424        }
8425    }
8426
8427    @Override
8428    public void stopLockTaskModeOnCurrent() throws RemoteException {
8429        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8430                "stopLockTaskModeOnCurrent");
8431        long ident = Binder.clearCallingIdentity();
8432        try {
8433            stopLockTaskMode();
8434        } finally {
8435            Binder.restoreCallingIdentity(ident);
8436        }
8437    }
8438
8439    @Override
8440    public boolean isInLockTaskMode() {
8441        synchronized (this) {
8442            return mStackSupervisor.isInLockTaskMode();
8443        }
8444    }
8445
8446    // =========================================================
8447    // CONTENT PROVIDERS
8448    // =========================================================
8449
8450    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8451        List<ProviderInfo> providers = null;
8452        try {
8453            providers = AppGlobals.getPackageManager().
8454                queryContentProviders(app.processName, app.uid,
8455                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8456        } catch (RemoteException ex) {
8457        }
8458        if (DEBUG_MU)
8459            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8460        int userId = app.userId;
8461        if (providers != null) {
8462            int N = providers.size();
8463            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8464            for (int i=0; i<N; i++) {
8465                ProviderInfo cpi =
8466                    (ProviderInfo)providers.get(i);
8467                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8468                        cpi.name, cpi.flags);
8469                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8470                    // This is a singleton provider, but a user besides the
8471                    // default user is asking to initialize a process it runs
8472                    // in...  well, no, it doesn't actually run in this process,
8473                    // it runs in the process of the default user.  Get rid of it.
8474                    providers.remove(i);
8475                    N--;
8476                    i--;
8477                    continue;
8478                }
8479
8480                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8481                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8482                if (cpr == null) {
8483                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8484                    mProviderMap.putProviderByClass(comp, cpr);
8485                }
8486                if (DEBUG_MU)
8487                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8488                app.pubProviders.put(cpi.name, cpr);
8489                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8490                    // Don't add this if it is a platform component that is marked
8491                    // to run in multiple processes, because this is actually
8492                    // part of the framework so doesn't make sense to track as a
8493                    // separate apk in the process.
8494                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8495                            mProcessStats);
8496                }
8497                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8498            }
8499        }
8500        return providers;
8501    }
8502
8503    /**
8504     * Check if {@link ProcessRecord} has a possible chance at accessing the
8505     * given {@link ProviderInfo}. Final permission checking is always done
8506     * in {@link ContentProvider}.
8507     */
8508    private final String checkContentProviderPermissionLocked(
8509            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8510        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8511        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8512        boolean checkedGrants = false;
8513        if (checkUser) {
8514            // Looking for cross-user grants before enforcing the typical cross-users permissions
8515            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8516            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8517                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8518                    return null;
8519                }
8520                checkedGrants = true;
8521            }
8522            userId = handleIncomingUser(callingPid, callingUid, userId,
8523                    false, ALLOW_NON_FULL,
8524                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8525            if (userId != tmpTargetUserId) {
8526                // When we actually went to determine the final targer user ID, this ended
8527                // up different than our initial check for the authority.  This is because
8528                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8529                // SELF.  So we need to re-check the grants again.
8530                checkedGrants = false;
8531            }
8532        }
8533        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8534                cpi.applicationInfo.uid, cpi.exported)
8535                == PackageManager.PERMISSION_GRANTED) {
8536            return null;
8537        }
8538        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8539                cpi.applicationInfo.uid, cpi.exported)
8540                == PackageManager.PERMISSION_GRANTED) {
8541            return null;
8542        }
8543
8544        PathPermission[] pps = cpi.pathPermissions;
8545        if (pps != null) {
8546            int i = pps.length;
8547            while (i > 0) {
8548                i--;
8549                PathPermission pp = pps[i];
8550                String pprperm = pp.getReadPermission();
8551                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8552                        cpi.applicationInfo.uid, cpi.exported)
8553                        == PackageManager.PERMISSION_GRANTED) {
8554                    return null;
8555                }
8556                String ppwperm = pp.getWritePermission();
8557                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8558                        cpi.applicationInfo.uid, cpi.exported)
8559                        == PackageManager.PERMISSION_GRANTED) {
8560                    return null;
8561                }
8562            }
8563        }
8564        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8565            return null;
8566        }
8567
8568        String msg;
8569        if (!cpi.exported) {
8570            msg = "Permission Denial: opening provider " + cpi.name
8571                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8572                    + ", uid=" + callingUid + ") that is not exported from uid "
8573                    + cpi.applicationInfo.uid;
8574        } else {
8575            msg = "Permission Denial: opening provider " + cpi.name
8576                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8577                    + ", uid=" + callingUid + ") requires "
8578                    + cpi.readPermission + " or " + cpi.writePermission;
8579        }
8580        Slog.w(TAG, msg);
8581        return msg;
8582    }
8583
8584    /**
8585     * Returns if the ContentProvider has granted a uri to callingUid
8586     */
8587    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8588        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8589        if (perms != null) {
8590            for (int i=perms.size()-1; i>=0; i--) {
8591                GrantUri grantUri = perms.keyAt(i);
8592                if (grantUri.sourceUserId == userId || !checkUser) {
8593                    if (matchesProvider(grantUri.uri, cpi)) {
8594                        return true;
8595                    }
8596                }
8597            }
8598        }
8599        return false;
8600    }
8601
8602    /**
8603     * Returns true if the uri authority is one of the authorities specified in the provider.
8604     */
8605    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8606        String uriAuth = uri.getAuthority();
8607        String cpiAuth = cpi.authority;
8608        if (cpiAuth.indexOf(';') == -1) {
8609            return cpiAuth.equals(uriAuth);
8610        }
8611        String[] cpiAuths = cpiAuth.split(";");
8612        int length = cpiAuths.length;
8613        for (int i = 0; i < length; i++) {
8614            if (cpiAuths[i].equals(uriAuth)) return true;
8615        }
8616        return false;
8617    }
8618
8619    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8620            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8621        if (r != null) {
8622            for (int i=0; i<r.conProviders.size(); i++) {
8623                ContentProviderConnection conn = r.conProviders.get(i);
8624                if (conn.provider == cpr) {
8625                    if (DEBUG_PROVIDER) Slog.v(TAG,
8626                            "Adding provider requested by "
8627                            + r.processName + " from process "
8628                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8629                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8630                    if (stable) {
8631                        conn.stableCount++;
8632                        conn.numStableIncs++;
8633                    } else {
8634                        conn.unstableCount++;
8635                        conn.numUnstableIncs++;
8636                    }
8637                    return conn;
8638                }
8639            }
8640            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8641            if (stable) {
8642                conn.stableCount = 1;
8643                conn.numStableIncs = 1;
8644            } else {
8645                conn.unstableCount = 1;
8646                conn.numUnstableIncs = 1;
8647            }
8648            cpr.connections.add(conn);
8649            r.conProviders.add(conn);
8650            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8651            return conn;
8652        }
8653        cpr.addExternalProcessHandleLocked(externalProcessToken);
8654        return null;
8655    }
8656
8657    boolean decProviderCountLocked(ContentProviderConnection conn,
8658            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8659        if (conn != null) {
8660            cpr = conn.provider;
8661            if (DEBUG_PROVIDER) Slog.v(TAG,
8662                    "Removing provider requested by "
8663                    + conn.client.processName + " from process "
8664                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8665                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8666            if (stable) {
8667                conn.stableCount--;
8668            } else {
8669                conn.unstableCount--;
8670            }
8671            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8672                cpr.connections.remove(conn);
8673                conn.client.conProviders.remove(conn);
8674                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8675                return true;
8676            }
8677            return false;
8678        }
8679        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8680        return false;
8681    }
8682
8683    private void checkTime(long startTime, String where) {
8684        long now = SystemClock.elapsedRealtime();
8685        if ((now-startTime) > 1000) {
8686            // If we are taking more than a second, log about it.
8687            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8688        }
8689    }
8690
8691    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8692            String name, IBinder token, boolean stable, int userId) {
8693        ContentProviderRecord cpr;
8694        ContentProviderConnection conn = null;
8695        ProviderInfo cpi = null;
8696
8697        synchronized(this) {
8698            long startTime = SystemClock.elapsedRealtime();
8699
8700            ProcessRecord r = null;
8701            if (caller != null) {
8702                r = getRecordForAppLocked(caller);
8703                if (r == null) {
8704                    throw new SecurityException(
8705                            "Unable to find app for caller " + caller
8706                          + " (pid=" + Binder.getCallingPid()
8707                          + ") when getting content provider " + name);
8708                }
8709            }
8710
8711            boolean checkCrossUser = true;
8712
8713            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8714
8715            // First check if this content provider has been published...
8716            cpr = mProviderMap.getProviderByName(name, userId);
8717            // If that didn't work, check if it exists for user 0 and then
8718            // verify that it's a singleton provider before using it.
8719            if (cpr == null && userId != UserHandle.USER_OWNER) {
8720                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8721                if (cpr != null) {
8722                    cpi = cpr.info;
8723                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8724                            cpi.name, cpi.flags)
8725                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8726                        userId = UserHandle.USER_OWNER;
8727                        checkCrossUser = false;
8728                    } else {
8729                        cpr = null;
8730                        cpi = null;
8731                    }
8732                }
8733            }
8734
8735            boolean providerRunning = cpr != null;
8736            if (providerRunning) {
8737                cpi = cpr.info;
8738                String msg;
8739                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8740                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8741                        != null) {
8742                    throw new SecurityException(msg);
8743                }
8744                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8745
8746                if (r != null && cpr.canRunHere(r)) {
8747                    // This provider has been published or is in the process
8748                    // of being published...  but it is also allowed to run
8749                    // in the caller's process, so don't make a connection
8750                    // and just let the caller instantiate its own instance.
8751                    ContentProviderHolder holder = cpr.newHolder(null);
8752                    // don't give caller the provider object, it needs
8753                    // to make its own.
8754                    holder.provider = null;
8755                    return holder;
8756                }
8757
8758                final long origId = Binder.clearCallingIdentity();
8759
8760                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8761
8762                // In this case the provider instance already exists, so we can
8763                // return it right away.
8764                conn = incProviderCountLocked(r, cpr, token, stable);
8765                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8766                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8767                        // If this is a perceptible app accessing the provider,
8768                        // make sure to count it as being accessed and thus
8769                        // back up on the LRU list.  This is good because
8770                        // content providers are often expensive to start.
8771                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8772                        updateLruProcessLocked(cpr.proc, false, null);
8773                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8774                    }
8775                }
8776
8777                if (cpr.proc != null) {
8778                    if (false) {
8779                        if (cpr.name.flattenToShortString().equals(
8780                                "com.android.providers.calendar/.CalendarProvider2")) {
8781                            Slog.v(TAG, "****************** KILLING "
8782                                + cpr.name.flattenToShortString());
8783                            Process.killProcess(cpr.proc.pid);
8784                        }
8785                    }
8786                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8787                    boolean success = updateOomAdjLocked(cpr.proc);
8788                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8789                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8790                    // NOTE: there is still a race here where a signal could be
8791                    // pending on the process even though we managed to update its
8792                    // adj level.  Not sure what to do about this, but at least
8793                    // the race is now smaller.
8794                    if (!success) {
8795                        // Uh oh...  it looks like the provider's process
8796                        // has been killed on us.  We need to wait for a new
8797                        // process to be started, and make sure its death
8798                        // doesn't kill our process.
8799                        Slog.i(TAG,
8800                                "Existing provider " + cpr.name.flattenToShortString()
8801                                + " is crashing; detaching " + r);
8802                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8803                        checkTime(startTime, "getContentProviderImpl: before appDied");
8804                        appDiedLocked(cpr.proc);
8805                        checkTime(startTime, "getContentProviderImpl: after appDied");
8806                        if (!lastRef) {
8807                            // This wasn't the last ref our process had on
8808                            // the provider...  we have now been killed, bail.
8809                            return null;
8810                        }
8811                        providerRunning = false;
8812                        conn = null;
8813                    }
8814                }
8815
8816                Binder.restoreCallingIdentity(origId);
8817            }
8818
8819            boolean singleton;
8820            if (!providerRunning) {
8821                try {
8822                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
8823                    cpi = AppGlobals.getPackageManager().
8824                        resolveContentProvider(name,
8825                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8826                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
8827                } catch (RemoteException ex) {
8828                }
8829                if (cpi == null) {
8830                    return null;
8831                }
8832                // If the provider is a singleton AND
8833                // (it's a call within the same user || the provider is a
8834                // privileged app)
8835                // Then allow connecting to the singleton provider
8836                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8837                        cpi.name, cpi.flags)
8838                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8839                if (singleton) {
8840                    userId = UserHandle.USER_OWNER;
8841                }
8842                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8843                checkTime(startTime, "getContentProviderImpl: got app info for user");
8844
8845                String msg;
8846                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8847                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8848                        != null) {
8849                    throw new SecurityException(msg);
8850                }
8851                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8852
8853                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8854                        && !cpi.processName.equals("system")) {
8855                    // If this content provider does not run in the system
8856                    // process, and the system is not yet ready to run other
8857                    // processes, then fail fast instead of hanging.
8858                    throw new IllegalArgumentException(
8859                            "Attempt to launch content provider before system ready");
8860                }
8861
8862                // Make sure that the user who owns this provider is running.  If not,
8863                // we don't want to allow it to run.
8864                if (!isUserRunningLocked(userId, false)) {
8865                    Slog.w(TAG, "Unable to launch app "
8866                            + cpi.applicationInfo.packageName + "/"
8867                            + cpi.applicationInfo.uid + " for provider "
8868                            + name + ": user " + userId + " is stopped");
8869                    return null;
8870                }
8871
8872                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8873                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
8874                cpr = mProviderMap.getProviderByClass(comp, userId);
8875                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
8876                final boolean firstClass = cpr == null;
8877                if (firstClass) {
8878                    final long ident = Binder.clearCallingIdentity();
8879                    try {
8880                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
8881                        ApplicationInfo ai =
8882                            AppGlobals.getPackageManager().
8883                                getApplicationInfo(
8884                                        cpi.applicationInfo.packageName,
8885                                        STOCK_PM_FLAGS, userId);
8886                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
8887                        if (ai == null) {
8888                            Slog.w(TAG, "No package info for content provider "
8889                                    + cpi.name);
8890                            return null;
8891                        }
8892                        ai = getAppInfoForUser(ai, userId);
8893                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8894                    } catch (RemoteException ex) {
8895                        // pm is in same process, this will never happen.
8896                    } finally {
8897                        Binder.restoreCallingIdentity(ident);
8898                    }
8899                }
8900
8901                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
8902
8903                if (r != null && cpr.canRunHere(r)) {
8904                    // If this is a multiprocess provider, then just return its
8905                    // info and allow the caller to instantiate it.  Only do
8906                    // this if the provider is the same user as the caller's
8907                    // process, or can run as root (so can be in any process).
8908                    return cpr.newHolder(null);
8909                }
8910
8911                if (DEBUG_PROVIDER) {
8912                    RuntimeException e = new RuntimeException("here");
8913                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8914                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8915                }
8916
8917                // This is single process, and our app is now connecting to it.
8918                // See if we are already in the process of launching this
8919                // provider.
8920                final int N = mLaunchingProviders.size();
8921                int i;
8922                for (i=0; i<N; i++) {
8923                    if (mLaunchingProviders.get(i) == cpr) {
8924                        break;
8925                    }
8926                }
8927
8928                // If the provider is not already being launched, then get it
8929                // started.
8930                if (i >= N) {
8931                    final long origId = Binder.clearCallingIdentity();
8932
8933                    try {
8934                        // Content provider is now in use, its package can't be stopped.
8935                        try {
8936                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
8937                            AppGlobals.getPackageManager().setPackageStoppedState(
8938                                    cpr.appInfo.packageName, false, userId);
8939                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
8940                        } catch (RemoteException e) {
8941                        } catch (IllegalArgumentException e) {
8942                            Slog.w(TAG, "Failed trying to unstop package "
8943                                    + cpr.appInfo.packageName + ": " + e);
8944                        }
8945
8946                        // Use existing process if already started
8947                        checkTime(startTime, "getContentProviderImpl: looking for process record");
8948                        ProcessRecord proc = getProcessRecordLocked(
8949                                cpi.processName, cpr.appInfo.uid, false);
8950                        if (proc != null && proc.thread != null) {
8951                            if (DEBUG_PROVIDER) {
8952                                Slog.d(TAG, "Installing in existing process " + proc);
8953                            }
8954                            if (!proc.pubProviders.containsKey(cpi.name)) {
8955                                checkTime(startTime, "getContentProviderImpl: scheduling install");
8956                                proc.pubProviders.put(cpi.name, cpr);
8957                                try {
8958                                    proc.thread.scheduleInstallProvider(cpi);
8959                                } catch (RemoteException e) {
8960                                }
8961                            }
8962                        } else {
8963                            checkTime(startTime, "getContentProviderImpl: before start process");
8964                            proc = startProcessLocked(cpi.processName,
8965                                    cpr.appInfo, false, 0, "content provider",
8966                                    new ComponentName(cpi.applicationInfo.packageName,
8967                                            cpi.name), false, false, false);
8968                            checkTime(startTime, "getContentProviderImpl: after start process");
8969                            if (proc == null) {
8970                                Slog.w(TAG, "Unable to launch app "
8971                                        + cpi.applicationInfo.packageName + "/"
8972                                        + cpi.applicationInfo.uid + " for provider "
8973                                        + name + ": process is bad");
8974                                return null;
8975                            }
8976                        }
8977                        cpr.launchingApp = proc;
8978                        mLaunchingProviders.add(cpr);
8979                    } finally {
8980                        Binder.restoreCallingIdentity(origId);
8981                    }
8982                }
8983
8984                checkTime(startTime, "getContentProviderImpl: updating data structures");
8985
8986                // Make sure the provider is published (the same provider class
8987                // may be published under multiple names).
8988                if (firstClass) {
8989                    mProviderMap.putProviderByClass(comp, cpr);
8990                }
8991
8992                mProviderMap.putProviderByName(name, cpr);
8993                conn = incProviderCountLocked(r, cpr, token, stable);
8994                if (conn != null) {
8995                    conn.waiting = true;
8996                }
8997            }
8998            checkTime(startTime, "getContentProviderImpl: done!");
8999        }
9000
9001        // Wait for the provider to be published...
9002        synchronized (cpr) {
9003            while (cpr.provider == null) {
9004                if (cpr.launchingApp == null) {
9005                    Slog.w(TAG, "Unable to launch app "
9006                            + cpi.applicationInfo.packageName + "/"
9007                            + cpi.applicationInfo.uid + " for provider "
9008                            + name + ": launching app became null");
9009                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9010                            UserHandle.getUserId(cpi.applicationInfo.uid),
9011                            cpi.applicationInfo.packageName,
9012                            cpi.applicationInfo.uid, name);
9013                    return null;
9014                }
9015                try {
9016                    if (DEBUG_MU) {
9017                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9018                                + cpr.launchingApp);
9019                    }
9020                    if (conn != null) {
9021                        conn.waiting = true;
9022                    }
9023                    cpr.wait();
9024                } catch (InterruptedException ex) {
9025                } finally {
9026                    if (conn != null) {
9027                        conn.waiting = false;
9028                    }
9029                }
9030            }
9031        }
9032        return cpr != null ? cpr.newHolder(conn) : null;
9033    }
9034
9035    @Override
9036    public final ContentProviderHolder getContentProvider(
9037            IApplicationThread caller, String name, int userId, boolean stable) {
9038        enforceNotIsolatedCaller("getContentProvider");
9039        if (caller == null) {
9040            String msg = "null IApplicationThread when getting content provider "
9041                    + name;
9042            Slog.w(TAG, msg);
9043            throw new SecurityException(msg);
9044        }
9045        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9046        // with cross-user grant.
9047        return getContentProviderImpl(caller, name, null, stable, userId);
9048    }
9049
9050    public ContentProviderHolder getContentProviderExternal(
9051            String name, int userId, IBinder token) {
9052        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9053            "Do not have permission in call getContentProviderExternal()");
9054        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9055                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9056        return getContentProviderExternalUnchecked(name, token, userId);
9057    }
9058
9059    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9060            IBinder token, int userId) {
9061        return getContentProviderImpl(null, name, token, true, userId);
9062    }
9063
9064    /**
9065     * Drop a content provider from a ProcessRecord's bookkeeping
9066     */
9067    public void removeContentProvider(IBinder connection, boolean stable) {
9068        enforceNotIsolatedCaller("removeContentProvider");
9069        long ident = Binder.clearCallingIdentity();
9070        try {
9071            synchronized (this) {
9072                ContentProviderConnection conn;
9073                try {
9074                    conn = (ContentProviderConnection)connection;
9075                } catch (ClassCastException e) {
9076                    String msg ="removeContentProvider: " + connection
9077                            + " not a ContentProviderConnection";
9078                    Slog.w(TAG, msg);
9079                    throw new IllegalArgumentException(msg);
9080                }
9081                if (conn == null) {
9082                    throw new NullPointerException("connection is null");
9083                }
9084                if (decProviderCountLocked(conn, null, null, stable)) {
9085                    updateOomAdjLocked();
9086                }
9087            }
9088        } finally {
9089            Binder.restoreCallingIdentity(ident);
9090        }
9091    }
9092
9093    public void removeContentProviderExternal(String name, IBinder token) {
9094        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9095            "Do not have permission in call removeContentProviderExternal()");
9096        int userId = UserHandle.getCallingUserId();
9097        long ident = Binder.clearCallingIdentity();
9098        try {
9099            removeContentProviderExternalUnchecked(name, token, userId);
9100        } finally {
9101            Binder.restoreCallingIdentity(ident);
9102        }
9103    }
9104
9105    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9106        synchronized (this) {
9107            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9108            if(cpr == null) {
9109                //remove from mProvidersByClass
9110                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9111                return;
9112            }
9113
9114            //update content provider record entry info
9115            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9116            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9117            if (localCpr.hasExternalProcessHandles()) {
9118                if (localCpr.removeExternalProcessHandleLocked(token)) {
9119                    updateOomAdjLocked();
9120                } else {
9121                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9122                            + " with no external reference for token: "
9123                            + token + ".");
9124                }
9125            } else {
9126                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9127                        + " with no external references.");
9128            }
9129        }
9130    }
9131
9132    public final void publishContentProviders(IApplicationThread caller,
9133            List<ContentProviderHolder> providers) {
9134        if (providers == null) {
9135            return;
9136        }
9137
9138        enforceNotIsolatedCaller("publishContentProviders");
9139        synchronized (this) {
9140            final ProcessRecord r = getRecordForAppLocked(caller);
9141            if (DEBUG_MU)
9142                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9143            if (r == null) {
9144                throw new SecurityException(
9145                        "Unable to find app for caller " + caller
9146                      + " (pid=" + Binder.getCallingPid()
9147                      + ") when publishing content providers");
9148            }
9149
9150            final long origId = Binder.clearCallingIdentity();
9151
9152            final int N = providers.size();
9153            for (int i=0; i<N; i++) {
9154                ContentProviderHolder src = providers.get(i);
9155                if (src == null || src.info == null || src.provider == null) {
9156                    continue;
9157                }
9158                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9159                if (DEBUG_MU)
9160                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9161                if (dst != null) {
9162                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9163                    mProviderMap.putProviderByClass(comp, dst);
9164                    String names[] = dst.info.authority.split(";");
9165                    for (int j = 0; j < names.length; j++) {
9166                        mProviderMap.putProviderByName(names[j], dst);
9167                    }
9168
9169                    int NL = mLaunchingProviders.size();
9170                    int j;
9171                    for (j=0; j<NL; j++) {
9172                        if (mLaunchingProviders.get(j) == dst) {
9173                            mLaunchingProviders.remove(j);
9174                            j--;
9175                            NL--;
9176                        }
9177                    }
9178                    synchronized (dst) {
9179                        dst.provider = src.provider;
9180                        dst.proc = r;
9181                        dst.notifyAll();
9182                    }
9183                    updateOomAdjLocked(r);
9184                }
9185            }
9186
9187            Binder.restoreCallingIdentity(origId);
9188        }
9189    }
9190
9191    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9192        ContentProviderConnection conn;
9193        try {
9194            conn = (ContentProviderConnection)connection;
9195        } catch (ClassCastException e) {
9196            String msg ="refContentProvider: " + connection
9197                    + " not a ContentProviderConnection";
9198            Slog.w(TAG, msg);
9199            throw new IllegalArgumentException(msg);
9200        }
9201        if (conn == null) {
9202            throw new NullPointerException("connection is null");
9203        }
9204
9205        synchronized (this) {
9206            if (stable > 0) {
9207                conn.numStableIncs += stable;
9208            }
9209            stable = conn.stableCount + stable;
9210            if (stable < 0) {
9211                throw new IllegalStateException("stableCount < 0: " + stable);
9212            }
9213
9214            if (unstable > 0) {
9215                conn.numUnstableIncs += unstable;
9216            }
9217            unstable = conn.unstableCount + unstable;
9218            if (unstable < 0) {
9219                throw new IllegalStateException("unstableCount < 0: " + unstable);
9220            }
9221
9222            if ((stable+unstable) <= 0) {
9223                throw new IllegalStateException("ref counts can't go to zero here: stable="
9224                        + stable + " unstable=" + unstable);
9225            }
9226            conn.stableCount = stable;
9227            conn.unstableCount = unstable;
9228            return !conn.dead;
9229        }
9230    }
9231
9232    public void unstableProviderDied(IBinder connection) {
9233        ContentProviderConnection conn;
9234        try {
9235            conn = (ContentProviderConnection)connection;
9236        } catch (ClassCastException e) {
9237            String msg ="refContentProvider: " + connection
9238                    + " not a ContentProviderConnection";
9239            Slog.w(TAG, msg);
9240            throw new IllegalArgumentException(msg);
9241        }
9242        if (conn == null) {
9243            throw new NullPointerException("connection is null");
9244        }
9245
9246        // Safely retrieve the content provider associated with the connection.
9247        IContentProvider provider;
9248        synchronized (this) {
9249            provider = conn.provider.provider;
9250        }
9251
9252        if (provider == null) {
9253            // Um, yeah, we're way ahead of you.
9254            return;
9255        }
9256
9257        // Make sure the caller is being honest with us.
9258        if (provider.asBinder().pingBinder()) {
9259            // Er, no, still looks good to us.
9260            synchronized (this) {
9261                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9262                        + " says " + conn + " died, but we don't agree");
9263                return;
9264            }
9265        }
9266
9267        // Well look at that!  It's dead!
9268        synchronized (this) {
9269            if (conn.provider.provider != provider) {
9270                // But something changed...  good enough.
9271                return;
9272            }
9273
9274            ProcessRecord proc = conn.provider.proc;
9275            if (proc == null || proc.thread == null) {
9276                // Seems like the process is already cleaned up.
9277                return;
9278            }
9279
9280            // As far as we're concerned, this is just like receiving a
9281            // death notification...  just a bit prematurely.
9282            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9283                    + ") early provider death");
9284            final long ident = Binder.clearCallingIdentity();
9285            try {
9286                appDiedLocked(proc);
9287            } finally {
9288                Binder.restoreCallingIdentity(ident);
9289            }
9290        }
9291    }
9292
9293    @Override
9294    public void appNotRespondingViaProvider(IBinder connection) {
9295        enforceCallingPermission(
9296                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9297
9298        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9299        if (conn == null) {
9300            Slog.w(TAG, "ContentProviderConnection is null");
9301            return;
9302        }
9303
9304        final ProcessRecord host = conn.provider.proc;
9305        if (host == null) {
9306            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9307            return;
9308        }
9309
9310        final long token = Binder.clearCallingIdentity();
9311        try {
9312            appNotResponding(host, null, null, false, "ContentProvider not responding");
9313        } finally {
9314            Binder.restoreCallingIdentity(token);
9315        }
9316    }
9317
9318    public final void installSystemProviders() {
9319        List<ProviderInfo> providers;
9320        synchronized (this) {
9321            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9322            providers = generateApplicationProvidersLocked(app);
9323            if (providers != null) {
9324                for (int i=providers.size()-1; i>=0; i--) {
9325                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9326                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9327                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9328                                + ": not system .apk");
9329                        providers.remove(i);
9330                    }
9331                }
9332            }
9333        }
9334        if (providers != null) {
9335            mSystemThread.installSystemProviders(providers);
9336        }
9337
9338        mCoreSettingsObserver = new CoreSettingsObserver(this);
9339
9340        //mUsageStatsService.monitorPackages();
9341    }
9342
9343    /**
9344     * Allows apps to retrieve the MIME type of a URI.
9345     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9346     * users, then it does not need permission to access the ContentProvider.
9347     * Either, it needs cross-user uri grants.
9348     *
9349     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9350     *
9351     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9352     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9353     */
9354    public String getProviderMimeType(Uri uri, int userId) {
9355        enforceNotIsolatedCaller("getProviderMimeType");
9356        final String name = uri.getAuthority();
9357        int callingUid = Binder.getCallingUid();
9358        int callingPid = Binder.getCallingPid();
9359        long ident = 0;
9360        boolean clearedIdentity = false;
9361        userId = unsafeConvertIncomingUser(userId);
9362        if (canClearIdentity(callingPid, callingUid, userId)) {
9363            clearedIdentity = true;
9364            ident = Binder.clearCallingIdentity();
9365        }
9366        ContentProviderHolder holder = null;
9367        try {
9368            holder = getContentProviderExternalUnchecked(name, null, userId);
9369            if (holder != null) {
9370                return holder.provider.getType(uri);
9371            }
9372        } catch (RemoteException e) {
9373            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9374            return null;
9375        } finally {
9376            // We need to clear the identity to call removeContentProviderExternalUnchecked
9377            if (!clearedIdentity) {
9378                ident = Binder.clearCallingIdentity();
9379            }
9380            try {
9381                if (holder != null) {
9382                    removeContentProviderExternalUnchecked(name, null, userId);
9383                }
9384            } finally {
9385                Binder.restoreCallingIdentity(ident);
9386            }
9387        }
9388
9389        return null;
9390    }
9391
9392    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9393        if (UserHandle.getUserId(callingUid) == userId) {
9394            return true;
9395        }
9396        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9397                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9398                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9399                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9400                return true;
9401        }
9402        return false;
9403    }
9404
9405    // =========================================================
9406    // GLOBAL MANAGEMENT
9407    // =========================================================
9408
9409    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9410            boolean isolated, int isolatedUid) {
9411        String proc = customProcess != null ? customProcess : info.processName;
9412        BatteryStatsImpl.Uid.Proc ps = null;
9413        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9414        int uid = info.uid;
9415        if (isolated) {
9416            if (isolatedUid == 0) {
9417                int userId = UserHandle.getUserId(uid);
9418                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9419                while (true) {
9420                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9421                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9422                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9423                    }
9424                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9425                    mNextIsolatedProcessUid++;
9426                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9427                        // No process for this uid, use it.
9428                        break;
9429                    }
9430                    stepsLeft--;
9431                    if (stepsLeft <= 0) {
9432                        return null;
9433                    }
9434                }
9435            } else {
9436                // Special case for startIsolatedProcess (internal only), where
9437                // the uid of the isolated process is specified by the caller.
9438                uid = isolatedUid;
9439            }
9440        }
9441        return new ProcessRecord(stats, info, proc, uid);
9442    }
9443
9444    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9445            String abiOverride) {
9446        ProcessRecord app;
9447        if (!isolated) {
9448            app = getProcessRecordLocked(info.processName, info.uid, true);
9449        } else {
9450            app = null;
9451        }
9452
9453        if (app == null) {
9454            app = newProcessRecordLocked(info, null, isolated, 0);
9455            mProcessNames.put(info.processName, app.uid, app);
9456            if (isolated) {
9457                mIsolatedProcesses.put(app.uid, app);
9458            }
9459            updateLruProcessLocked(app, false, null);
9460            updateOomAdjLocked();
9461        }
9462
9463        // This package really, really can not be stopped.
9464        try {
9465            AppGlobals.getPackageManager().setPackageStoppedState(
9466                    info.packageName, false, UserHandle.getUserId(app.uid));
9467        } catch (RemoteException e) {
9468        } catch (IllegalArgumentException e) {
9469            Slog.w(TAG, "Failed trying to unstop package "
9470                    + info.packageName + ": " + e);
9471        }
9472
9473        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9474                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9475            app.persistent = true;
9476            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9477        }
9478        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9479            mPersistentStartingProcesses.add(app);
9480            startProcessLocked(app, "added application", app.processName, abiOverride,
9481                    null /* entryPoint */, null /* entryPointArgs */);
9482        }
9483
9484        return app;
9485    }
9486
9487    public void unhandledBack() {
9488        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9489                "unhandledBack()");
9490
9491        synchronized(this) {
9492            final long origId = Binder.clearCallingIdentity();
9493            try {
9494                getFocusedStack().unhandledBackLocked();
9495            } finally {
9496                Binder.restoreCallingIdentity(origId);
9497            }
9498        }
9499    }
9500
9501    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9502        enforceNotIsolatedCaller("openContentUri");
9503        final int userId = UserHandle.getCallingUserId();
9504        String name = uri.getAuthority();
9505        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9506        ParcelFileDescriptor pfd = null;
9507        if (cph != null) {
9508            // We record the binder invoker's uid in thread-local storage before
9509            // going to the content provider to open the file.  Later, in the code
9510            // that handles all permissions checks, we look for this uid and use
9511            // that rather than the Activity Manager's own uid.  The effect is that
9512            // we do the check against the caller's permissions even though it looks
9513            // to the content provider like the Activity Manager itself is making
9514            // the request.
9515            Binder token = new Binder();
9516            sCallerIdentity.set(new Identity(
9517                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9518            try {
9519                pfd = cph.provider.openFile(null, uri, "r", null, token);
9520            } catch (FileNotFoundException e) {
9521                // do nothing; pfd will be returned null
9522            } finally {
9523                // Ensure that whatever happens, we clean up the identity state
9524                sCallerIdentity.remove();
9525                // Ensure we're done with the provider.
9526                removeContentProviderExternalUnchecked(name, null, userId);
9527            }
9528        } else {
9529            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9530        }
9531        return pfd;
9532    }
9533
9534    // Actually is sleeping or shutting down or whatever else in the future
9535    // is an inactive state.
9536    public boolean isSleepingOrShuttingDown() {
9537        return isSleeping() || mShuttingDown;
9538    }
9539
9540    public boolean isSleeping() {
9541        return mSleeping;
9542    }
9543
9544    void onWakefulnessChanged(int wakefulness) {
9545        synchronized(this) {
9546            mWakefulness = wakefulness;
9547            updateSleepIfNeededLocked();
9548        }
9549    }
9550
9551    void finishRunningVoiceLocked() {
9552        if (mRunningVoice) {
9553            mRunningVoice = false;
9554            updateSleepIfNeededLocked();
9555        }
9556    }
9557
9558    void updateSleepIfNeededLocked() {
9559        if (mSleeping && !shouldSleepLocked()) {
9560            mSleeping = false;
9561            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9562        } else if (!mSleeping && shouldSleepLocked()) {
9563            mSleeping = true;
9564            mStackSupervisor.goingToSleepLocked();
9565
9566            // Initialize the wake times of all processes.
9567            checkExcessivePowerUsageLocked(false);
9568            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9569            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9570            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9571        }
9572    }
9573
9574    private boolean shouldSleepLocked() {
9575        // Resume applications while running a voice interactor.
9576        if (mRunningVoice) {
9577            return false;
9578        }
9579
9580        switch (mWakefulness) {
9581            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9582            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9583                // If we're interactive but applications are already paused then defer
9584                // resuming them until the lock screen is hidden.
9585                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9586            case PowerManagerInternal.WAKEFULNESS_DOZING:
9587                // If we're dozing then pause applications whenever the lock screen is shown.
9588                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9589            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9590            default:
9591                // If we're asleep then pause applications unconditionally.
9592                return true;
9593        }
9594    }
9595
9596    /** Pokes the task persister. */
9597    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9598        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9599            // Never persist the home stack.
9600            return;
9601        }
9602        mTaskPersister.wakeup(task, flush);
9603    }
9604
9605    /** Notifies all listeners when the task stack has changed. */
9606    void notifyTaskStackChangedLocked() {
9607        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9608        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9609        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9610    }
9611
9612    @Override
9613    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9614        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9615    }
9616
9617    @Override
9618    public boolean shutdown(int timeout) {
9619        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9620                != PackageManager.PERMISSION_GRANTED) {
9621            throw new SecurityException("Requires permission "
9622                    + android.Manifest.permission.SHUTDOWN);
9623        }
9624
9625        boolean timedout = false;
9626
9627        synchronized(this) {
9628            mShuttingDown = true;
9629            updateEventDispatchingLocked();
9630            timedout = mStackSupervisor.shutdownLocked(timeout);
9631        }
9632
9633        mAppOpsService.shutdown();
9634        if (mUsageStatsService != null) {
9635            mUsageStatsService.prepareShutdown();
9636        }
9637        mBatteryStatsService.shutdown();
9638        synchronized (this) {
9639            mProcessStats.shutdownLocked();
9640            notifyTaskPersisterLocked(null, true);
9641        }
9642
9643        return timedout;
9644    }
9645
9646    public final void activitySlept(IBinder token) {
9647        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9648
9649        final long origId = Binder.clearCallingIdentity();
9650
9651        synchronized (this) {
9652            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9653            if (r != null) {
9654                mStackSupervisor.activitySleptLocked(r);
9655            }
9656        }
9657
9658        Binder.restoreCallingIdentity(origId);
9659    }
9660
9661    private String lockScreenShownToString() {
9662        switch (mLockScreenShown) {
9663            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9664            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9665            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9666            default: return "Unknown=" + mLockScreenShown;
9667        }
9668    }
9669
9670    void logLockScreen(String msg) {
9671        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
9672                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9673                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9674                + " mSleeping=" + mSleeping);
9675    }
9676
9677    void startRunningVoiceLocked() {
9678        if (!mRunningVoice) {
9679            mRunningVoice = true;
9680            updateSleepIfNeededLocked();
9681        }
9682    }
9683
9684    private void updateEventDispatchingLocked() {
9685        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9686    }
9687
9688    public void setLockScreenShown(boolean shown) {
9689        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9690                != PackageManager.PERMISSION_GRANTED) {
9691            throw new SecurityException("Requires permission "
9692                    + android.Manifest.permission.DEVICE_POWER);
9693        }
9694
9695        synchronized(this) {
9696            long ident = Binder.clearCallingIdentity();
9697            try {
9698                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9699                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9700                updateSleepIfNeededLocked();
9701            } finally {
9702                Binder.restoreCallingIdentity(ident);
9703            }
9704        }
9705    }
9706
9707    @Override
9708    public void stopAppSwitches() {
9709        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9710                != PackageManager.PERMISSION_GRANTED) {
9711            throw new SecurityException("Requires permission "
9712                    + android.Manifest.permission.STOP_APP_SWITCHES);
9713        }
9714
9715        synchronized(this) {
9716            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9717                    + APP_SWITCH_DELAY_TIME;
9718            mDidAppSwitch = false;
9719            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9720            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9721            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9722        }
9723    }
9724
9725    public void resumeAppSwitches() {
9726        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9727                != PackageManager.PERMISSION_GRANTED) {
9728            throw new SecurityException("Requires permission "
9729                    + android.Manifest.permission.STOP_APP_SWITCHES);
9730        }
9731
9732        synchronized(this) {
9733            // Note that we don't execute any pending app switches... we will
9734            // let those wait until either the timeout, or the next start
9735            // activity request.
9736            mAppSwitchesAllowedTime = 0;
9737        }
9738    }
9739
9740    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9741            int callingPid, int callingUid, String name) {
9742        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9743            return true;
9744        }
9745
9746        int perm = checkComponentPermission(
9747                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9748                sourceUid, -1, true);
9749        if (perm == PackageManager.PERMISSION_GRANTED) {
9750            return true;
9751        }
9752
9753        // If the actual IPC caller is different from the logical source, then
9754        // also see if they are allowed to control app switches.
9755        if (callingUid != -1 && callingUid != sourceUid) {
9756            perm = checkComponentPermission(
9757                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9758                    callingUid, -1, true);
9759            if (perm == PackageManager.PERMISSION_GRANTED) {
9760                return true;
9761            }
9762        }
9763
9764        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9765        return false;
9766    }
9767
9768    public void setDebugApp(String packageName, boolean waitForDebugger,
9769            boolean persistent) {
9770        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9771                "setDebugApp()");
9772
9773        long ident = Binder.clearCallingIdentity();
9774        try {
9775            // Note that this is not really thread safe if there are multiple
9776            // callers into it at the same time, but that's not a situation we
9777            // care about.
9778            if (persistent) {
9779                final ContentResolver resolver = mContext.getContentResolver();
9780                Settings.Global.putString(
9781                    resolver, Settings.Global.DEBUG_APP,
9782                    packageName);
9783                Settings.Global.putInt(
9784                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9785                    waitForDebugger ? 1 : 0);
9786            }
9787
9788            synchronized (this) {
9789                if (!persistent) {
9790                    mOrigDebugApp = mDebugApp;
9791                    mOrigWaitForDebugger = mWaitForDebugger;
9792                }
9793                mDebugApp = packageName;
9794                mWaitForDebugger = waitForDebugger;
9795                mDebugTransient = !persistent;
9796                if (packageName != null) {
9797                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9798                            false, UserHandle.USER_ALL, "set debug app");
9799                }
9800            }
9801        } finally {
9802            Binder.restoreCallingIdentity(ident);
9803        }
9804    }
9805
9806    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9807        synchronized (this) {
9808            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9809            if (!isDebuggable) {
9810                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9811                    throw new SecurityException("Process not debuggable: " + app.packageName);
9812                }
9813            }
9814
9815            mOpenGlTraceApp = processName;
9816        }
9817    }
9818
9819    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9820        synchronized (this) {
9821            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9822            if (!isDebuggable) {
9823                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9824                    throw new SecurityException("Process not debuggable: " + app.packageName);
9825                }
9826            }
9827            mProfileApp = processName;
9828            mProfileFile = profilerInfo.profileFile;
9829            if (mProfileFd != null) {
9830                try {
9831                    mProfileFd.close();
9832                } catch (IOException e) {
9833                }
9834                mProfileFd = null;
9835            }
9836            mProfileFd = profilerInfo.profileFd;
9837            mSamplingInterval = profilerInfo.samplingInterval;
9838            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9839            mProfileType = 0;
9840        }
9841    }
9842
9843    @Override
9844    public void setAlwaysFinish(boolean enabled) {
9845        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9846                "setAlwaysFinish()");
9847
9848        Settings.Global.putInt(
9849                mContext.getContentResolver(),
9850                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9851
9852        synchronized (this) {
9853            mAlwaysFinishActivities = enabled;
9854        }
9855    }
9856
9857    @Override
9858    public void setActivityController(IActivityController controller) {
9859        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9860                "setActivityController()");
9861        synchronized (this) {
9862            mController = controller;
9863            Watchdog.getInstance().setActivityController(controller);
9864        }
9865    }
9866
9867    @Override
9868    public void setUserIsMonkey(boolean userIsMonkey) {
9869        synchronized (this) {
9870            synchronized (mPidsSelfLocked) {
9871                final int callingPid = Binder.getCallingPid();
9872                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9873                if (precessRecord == null) {
9874                    throw new SecurityException("Unknown process: " + callingPid);
9875                }
9876                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9877                    throw new SecurityException("Only an instrumentation process "
9878                            + "with a UiAutomation can call setUserIsMonkey");
9879                }
9880            }
9881            mUserIsMonkey = userIsMonkey;
9882        }
9883    }
9884
9885    @Override
9886    public boolean isUserAMonkey() {
9887        synchronized (this) {
9888            // If there is a controller also implies the user is a monkey.
9889            return (mUserIsMonkey || mController != null);
9890        }
9891    }
9892
9893    public void requestBugReport() {
9894        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9895        SystemProperties.set("ctl.start", "bugreport");
9896    }
9897
9898    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9899        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9900    }
9901
9902    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9903        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9904            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9905        }
9906        return KEY_DISPATCHING_TIMEOUT;
9907    }
9908
9909    @Override
9910    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9911        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9912                != PackageManager.PERMISSION_GRANTED) {
9913            throw new SecurityException("Requires permission "
9914                    + android.Manifest.permission.FILTER_EVENTS);
9915        }
9916        ProcessRecord proc;
9917        long timeout;
9918        synchronized (this) {
9919            synchronized (mPidsSelfLocked) {
9920                proc = mPidsSelfLocked.get(pid);
9921            }
9922            timeout = getInputDispatchingTimeoutLocked(proc);
9923        }
9924
9925        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9926            return -1;
9927        }
9928
9929        return timeout;
9930    }
9931
9932    /**
9933     * Handle input dispatching timeouts.
9934     * Returns whether input dispatching should be aborted or not.
9935     */
9936    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9937            final ActivityRecord activity, final ActivityRecord parent,
9938            final boolean aboveSystem, String reason) {
9939        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9940                != PackageManager.PERMISSION_GRANTED) {
9941            throw new SecurityException("Requires permission "
9942                    + android.Manifest.permission.FILTER_EVENTS);
9943        }
9944
9945        final String annotation;
9946        if (reason == null) {
9947            annotation = "Input dispatching timed out";
9948        } else {
9949            annotation = "Input dispatching timed out (" + reason + ")";
9950        }
9951
9952        if (proc != null) {
9953            synchronized (this) {
9954                if (proc.debugging) {
9955                    return false;
9956                }
9957
9958                if (mDidDexOpt) {
9959                    // Give more time since we were dexopting.
9960                    mDidDexOpt = false;
9961                    return false;
9962                }
9963
9964                if (proc.instrumentationClass != null) {
9965                    Bundle info = new Bundle();
9966                    info.putString("shortMsg", "keyDispatchingTimedOut");
9967                    info.putString("longMsg", annotation);
9968                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9969                    return true;
9970                }
9971            }
9972            mHandler.post(new Runnable() {
9973                @Override
9974                public void run() {
9975                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9976                }
9977            });
9978        }
9979
9980        return true;
9981    }
9982
9983    public Bundle getAssistContextExtras(int requestType) {
9984        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
9985                UserHandle.getCallingUserId());
9986        if (pae == null) {
9987            return null;
9988        }
9989        synchronized (pae) {
9990            while (!pae.haveResult) {
9991                try {
9992                    pae.wait();
9993                } catch (InterruptedException e) {
9994                }
9995            }
9996            if (pae.result != null) {
9997                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9998            }
9999        }
10000        synchronized (this) {
10001            mPendingAssistExtras.remove(pae);
10002            mHandler.removeCallbacks(pae);
10003        }
10004        return pae.extras;
10005    }
10006
10007    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10008            int userHandle) {
10009        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10010                "getAssistContextExtras()");
10011        PendingAssistExtras pae;
10012        Bundle extras = new Bundle();
10013        synchronized (this) {
10014            ActivityRecord activity = getFocusedStack().mResumedActivity;
10015            if (activity == null) {
10016                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10017                return null;
10018            }
10019            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10020            if (activity.app == null || activity.app.thread == null) {
10021                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10022                return null;
10023            }
10024            if (activity.app.pid == Binder.getCallingPid()) {
10025                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10026                return null;
10027            }
10028            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10029            try {
10030                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10031                        requestType);
10032                mPendingAssistExtras.add(pae);
10033                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10034            } catch (RemoteException e) {
10035                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10036                return null;
10037            }
10038            return pae;
10039        }
10040    }
10041
10042    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10043        PendingAssistExtras pae = (PendingAssistExtras)token;
10044        synchronized (pae) {
10045            pae.result = extras;
10046            pae.haveResult = true;
10047            pae.notifyAll();
10048            if (pae.intent == null) {
10049                // Caller is just waiting for the result.
10050                return;
10051            }
10052        }
10053
10054        // We are now ready to launch the assist activity.
10055        synchronized (this) {
10056            boolean exists = mPendingAssistExtras.remove(pae);
10057            mHandler.removeCallbacks(pae);
10058            if (!exists) {
10059                // Timed out.
10060                return;
10061            }
10062        }
10063        pae.intent.replaceExtras(extras);
10064        if (pae.hint != null) {
10065            pae.intent.putExtra(pae.hint, true);
10066        }
10067        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10068                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10069                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10070        closeSystemDialogs("assist");
10071        try {
10072            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10073        } catch (ActivityNotFoundException e) {
10074            Slog.w(TAG, "No activity to handle assist action.", e);
10075        }
10076    }
10077
10078    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10079        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10080    }
10081
10082    public void registerProcessObserver(IProcessObserver observer) {
10083        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10084                "registerProcessObserver()");
10085        synchronized (this) {
10086            mProcessObservers.register(observer);
10087        }
10088    }
10089
10090    @Override
10091    public void unregisterProcessObserver(IProcessObserver observer) {
10092        synchronized (this) {
10093            mProcessObservers.unregister(observer);
10094        }
10095    }
10096
10097    @Override
10098    public boolean convertFromTranslucent(IBinder token) {
10099        final long origId = Binder.clearCallingIdentity();
10100        try {
10101            synchronized (this) {
10102                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10103                if (r == null) {
10104                    return false;
10105                }
10106                final boolean translucentChanged = r.changeWindowTranslucency(true);
10107                if (translucentChanged) {
10108                    r.task.stack.releaseBackgroundResources(r);
10109                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10110                }
10111                mWindowManager.setAppFullscreen(token, true);
10112                return translucentChanged;
10113            }
10114        } finally {
10115            Binder.restoreCallingIdentity(origId);
10116        }
10117    }
10118
10119    @Override
10120    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10121        final long origId = Binder.clearCallingIdentity();
10122        try {
10123            synchronized (this) {
10124                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10125                if (r == null) {
10126                    return false;
10127                }
10128                int index = r.task.mActivities.lastIndexOf(r);
10129                if (index > 0) {
10130                    ActivityRecord under = r.task.mActivities.get(index - 1);
10131                    under.returningOptions = options;
10132                }
10133                final boolean translucentChanged = r.changeWindowTranslucency(false);
10134                if (translucentChanged) {
10135                    r.task.stack.convertActivityToTranslucent(r);
10136                }
10137                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10138                mWindowManager.setAppFullscreen(token, false);
10139                return translucentChanged;
10140            }
10141        } finally {
10142            Binder.restoreCallingIdentity(origId);
10143        }
10144    }
10145
10146    @Override
10147    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10148        final long origId = Binder.clearCallingIdentity();
10149        try {
10150            synchronized (this) {
10151                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10152                if (r != null) {
10153                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10154                }
10155            }
10156            return false;
10157        } finally {
10158            Binder.restoreCallingIdentity(origId);
10159        }
10160    }
10161
10162    @Override
10163    public boolean isBackgroundVisibleBehind(IBinder token) {
10164        final long origId = Binder.clearCallingIdentity();
10165        try {
10166            synchronized (this) {
10167                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10168                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10169                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10170                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10171                return visible;
10172            }
10173        } finally {
10174            Binder.restoreCallingIdentity(origId);
10175        }
10176    }
10177
10178    @Override
10179    public ActivityOptions getActivityOptions(IBinder token) {
10180        final long origId = Binder.clearCallingIdentity();
10181        try {
10182            synchronized (this) {
10183                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10184                if (r != null) {
10185                    final ActivityOptions activityOptions = r.pendingOptions;
10186                    r.pendingOptions = null;
10187                    return activityOptions;
10188                }
10189                return null;
10190            }
10191        } finally {
10192            Binder.restoreCallingIdentity(origId);
10193        }
10194    }
10195
10196    @Override
10197    public void setImmersive(IBinder token, boolean immersive) {
10198        synchronized(this) {
10199            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10200            if (r == null) {
10201                throw new IllegalArgumentException();
10202            }
10203            r.immersive = immersive;
10204
10205            // update associated state if we're frontmost
10206            if (r == mFocusedActivity) {
10207                if (DEBUG_IMMERSIVE) {
10208                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10209                }
10210                applyUpdateLockStateLocked(r);
10211            }
10212        }
10213    }
10214
10215    @Override
10216    public boolean isImmersive(IBinder token) {
10217        synchronized (this) {
10218            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10219            if (r == null) {
10220                throw new IllegalArgumentException();
10221            }
10222            return r.immersive;
10223        }
10224    }
10225
10226    public boolean isTopActivityImmersive() {
10227        enforceNotIsolatedCaller("startActivity");
10228        synchronized (this) {
10229            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10230            return (r != null) ? r.immersive : false;
10231        }
10232    }
10233
10234    @Override
10235    public boolean isTopOfTask(IBinder token) {
10236        synchronized (this) {
10237            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10238            if (r == null) {
10239                throw new IllegalArgumentException();
10240            }
10241            return r.task.getTopActivity() == r;
10242        }
10243    }
10244
10245    public final void enterSafeMode() {
10246        synchronized(this) {
10247            // It only makes sense to do this before the system is ready
10248            // and started launching other packages.
10249            if (!mSystemReady) {
10250                try {
10251                    AppGlobals.getPackageManager().enterSafeMode();
10252                } catch (RemoteException e) {
10253                }
10254            }
10255
10256            mSafeMode = true;
10257        }
10258    }
10259
10260    public final void showSafeModeOverlay() {
10261        View v = LayoutInflater.from(mContext).inflate(
10262                com.android.internal.R.layout.safe_mode, null);
10263        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10264        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10265        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10266        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10267        lp.gravity = Gravity.BOTTOM | Gravity.START;
10268        lp.format = v.getBackground().getOpacity();
10269        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10270                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10271        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10272        ((WindowManager)mContext.getSystemService(
10273                Context.WINDOW_SERVICE)).addView(v, lp);
10274    }
10275
10276    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10277        if (!(sender instanceof PendingIntentRecord)) {
10278            return;
10279        }
10280        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10281        synchronized (stats) {
10282            if (mBatteryStatsService.isOnBattery()) {
10283                mBatteryStatsService.enforceCallingPermission();
10284                PendingIntentRecord rec = (PendingIntentRecord)sender;
10285                int MY_UID = Binder.getCallingUid();
10286                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10287                BatteryStatsImpl.Uid.Pkg pkg =
10288                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10289                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10290                pkg.incWakeupsLocked();
10291            }
10292        }
10293    }
10294
10295    public boolean killPids(int[] pids, String pReason, boolean secure) {
10296        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10297            throw new SecurityException("killPids only available to the system");
10298        }
10299        String reason = (pReason == null) ? "Unknown" : pReason;
10300        // XXX Note: don't acquire main activity lock here, because the window
10301        // manager calls in with its locks held.
10302
10303        boolean killed = false;
10304        synchronized (mPidsSelfLocked) {
10305            int[] types = new int[pids.length];
10306            int worstType = 0;
10307            for (int i=0; i<pids.length; i++) {
10308                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10309                if (proc != null) {
10310                    int type = proc.setAdj;
10311                    types[i] = type;
10312                    if (type > worstType) {
10313                        worstType = type;
10314                    }
10315                }
10316            }
10317
10318            // If the worst oom_adj is somewhere in the cached proc LRU range,
10319            // then constrain it so we will kill all cached procs.
10320            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10321                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10322                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10323            }
10324
10325            // If this is not a secure call, don't let it kill processes that
10326            // are important.
10327            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10328                worstType = ProcessList.SERVICE_ADJ;
10329            }
10330
10331            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10332            for (int i=0; i<pids.length; i++) {
10333                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10334                if (proc == null) {
10335                    continue;
10336                }
10337                int adj = proc.setAdj;
10338                if (adj >= worstType && !proc.killedByAm) {
10339                    proc.kill(reason, true);
10340                    killed = true;
10341                }
10342            }
10343        }
10344        return killed;
10345    }
10346
10347    @Override
10348    public void killUid(int uid, String reason) {
10349        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10350            throw new SecurityException("killUid only available to the system");
10351        }
10352        synchronized (this) {
10353            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10354                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10355                    reason != null ? reason : "kill uid");
10356        }
10357    }
10358
10359    @Override
10360    public boolean killProcessesBelowForeground(String reason) {
10361        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10362            throw new SecurityException("killProcessesBelowForeground() only available to system");
10363        }
10364
10365        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10366    }
10367
10368    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10369        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10370            throw new SecurityException("killProcessesBelowAdj() only available to system");
10371        }
10372
10373        boolean killed = false;
10374        synchronized (mPidsSelfLocked) {
10375            final int size = mPidsSelfLocked.size();
10376            for (int i = 0; i < size; i++) {
10377                final int pid = mPidsSelfLocked.keyAt(i);
10378                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10379                if (proc == null) continue;
10380
10381                final int adj = proc.setAdj;
10382                if (adj > belowAdj && !proc.killedByAm) {
10383                    proc.kill(reason, true);
10384                    killed = true;
10385                }
10386            }
10387        }
10388        return killed;
10389    }
10390
10391    @Override
10392    public void hang(final IBinder who, boolean allowRestart) {
10393        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10394                != PackageManager.PERMISSION_GRANTED) {
10395            throw new SecurityException("Requires permission "
10396                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10397        }
10398
10399        final IBinder.DeathRecipient death = new DeathRecipient() {
10400            @Override
10401            public void binderDied() {
10402                synchronized (this) {
10403                    notifyAll();
10404                }
10405            }
10406        };
10407
10408        try {
10409            who.linkToDeath(death, 0);
10410        } catch (RemoteException e) {
10411            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10412            return;
10413        }
10414
10415        synchronized (this) {
10416            Watchdog.getInstance().setAllowRestart(allowRestart);
10417            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10418            synchronized (death) {
10419                while (who.isBinderAlive()) {
10420                    try {
10421                        death.wait();
10422                    } catch (InterruptedException e) {
10423                    }
10424                }
10425            }
10426            Watchdog.getInstance().setAllowRestart(true);
10427        }
10428    }
10429
10430    @Override
10431    public void restart() {
10432        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10433                != PackageManager.PERMISSION_GRANTED) {
10434            throw new SecurityException("Requires permission "
10435                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10436        }
10437
10438        Log.i(TAG, "Sending shutdown broadcast...");
10439
10440        BroadcastReceiver br = new BroadcastReceiver() {
10441            @Override public void onReceive(Context context, Intent intent) {
10442                // Now the broadcast is done, finish up the low-level shutdown.
10443                Log.i(TAG, "Shutting down activity manager...");
10444                shutdown(10000);
10445                Log.i(TAG, "Shutdown complete, restarting!");
10446                Process.killProcess(Process.myPid());
10447                System.exit(10);
10448            }
10449        };
10450
10451        // First send the high-level shut down broadcast.
10452        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10453        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10454        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10455        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10456        mContext.sendOrderedBroadcastAsUser(intent,
10457                UserHandle.ALL, null, br, mHandler, 0, null, null);
10458        */
10459        br.onReceive(mContext, intent);
10460    }
10461
10462    private long getLowRamTimeSinceIdle(long now) {
10463        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10464    }
10465
10466    @Override
10467    public void performIdleMaintenance() {
10468        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10469                != PackageManager.PERMISSION_GRANTED) {
10470            throw new SecurityException("Requires permission "
10471                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10472        }
10473
10474        synchronized (this) {
10475            final long now = SystemClock.uptimeMillis();
10476            final long timeSinceLastIdle = now - mLastIdleTime;
10477            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10478            mLastIdleTime = now;
10479            mLowRamTimeSinceLastIdle = 0;
10480            if (mLowRamStartTime != 0) {
10481                mLowRamStartTime = now;
10482            }
10483
10484            StringBuilder sb = new StringBuilder(128);
10485            sb.append("Idle maintenance over ");
10486            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10487            sb.append(" low RAM for ");
10488            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10489            Slog.i(TAG, sb.toString());
10490
10491            // If at least 1/3 of our time since the last idle period has been spent
10492            // with RAM low, then we want to kill processes.
10493            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10494
10495            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10496                ProcessRecord proc = mLruProcesses.get(i);
10497                if (proc.notCachedSinceIdle) {
10498                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10499                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10500                        if (doKilling && proc.initialIdlePss != 0
10501                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10502                            sb = new StringBuilder(128);
10503                            sb.append("Kill");
10504                            sb.append(proc.processName);
10505                            sb.append(" in idle maint: pss=");
10506                            sb.append(proc.lastPss);
10507                            sb.append(", initialPss=");
10508                            sb.append(proc.initialIdlePss);
10509                            sb.append(", period=");
10510                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10511                            sb.append(", lowRamPeriod=");
10512                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10513                            Slog.wtfQuiet(TAG, sb.toString());
10514                            proc.kill("idle maint (pss " + proc.lastPss
10515                                    + " from " + proc.initialIdlePss + ")", true);
10516                        }
10517                    }
10518                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10519                    proc.notCachedSinceIdle = true;
10520                    proc.initialIdlePss = 0;
10521                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10522                            mTestPssMode, isSleeping(), now);
10523                }
10524            }
10525
10526            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10527            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10528        }
10529    }
10530
10531    private void retrieveSettings() {
10532        final ContentResolver resolver = mContext.getContentResolver();
10533        String debugApp = Settings.Global.getString(
10534            resolver, Settings.Global.DEBUG_APP);
10535        boolean waitForDebugger = Settings.Global.getInt(
10536            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10537        boolean alwaysFinishActivities = Settings.Global.getInt(
10538            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10539        boolean forceRtl = Settings.Global.getInt(
10540                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10541        // Transfer any global setting for forcing RTL layout, into a System Property
10542        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10543
10544        Configuration configuration = new Configuration();
10545        Settings.System.getConfiguration(resolver, configuration);
10546        if (forceRtl) {
10547            // This will take care of setting the correct layout direction flags
10548            configuration.setLayoutDirection(configuration.locale);
10549        }
10550
10551        synchronized (this) {
10552            mDebugApp = mOrigDebugApp = debugApp;
10553            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10554            mAlwaysFinishActivities = alwaysFinishActivities;
10555            // This happens before any activities are started, so we can
10556            // change mConfiguration in-place.
10557            updateConfigurationLocked(configuration, null, false, true);
10558            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10559        }
10560    }
10561
10562    /** Loads resources after the current configuration has been set. */
10563    private void loadResourcesOnSystemReady() {
10564        final Resources res = mContext.getResources();
10565        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10566        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10567        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10568    }
10569
10570    public boolean testIsSystemReady() {
10571        // no need to synchronize(this) just to read & return the value
10572        return mSystemReady;
10573    }
10574
10575    private static File getCalledPreBootReceiversFile() {
10576        File dataDir = Environment.getDataDirectory();
10577        File systemDir = new File(dataDir, "system");
10578        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10579        return fname;
10580    }
10581
10582    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10583        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10584        File file = getCalledPreBootReceiversFile();
10585        FileInputStream fis = null;
10586        try {
10587            fis = new FileInputStream(file);
10588            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10589            int fvers = dis.readInt();
10590            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10591                String vers = dis.readUTF();
10592                String codename = dis.readUTF();
10593                String build = dis.readUTF();
10594                if (android.os.Build.VERSION.RELEASE.equals(vers)
10595                        && android.os.Build.VERSION.CODENAME.equals(codename)
10596                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10597                    int num = dis.readInt();
10598                    while (num > 0) {
10599                        num--;
10600                        String pkg = dis.readUTF();
10601                        String cls = dis.readUTF();
10602                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10603                    }
10604                }
10605            }
10606        } catch (FileNotFoundException e) {
10607        } catch (IOException e) {
10608            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10609        } finally {
10610            if (fis != null) {
10611                try {
10612                    fis.close();
10613                } catch (IOException e) {
10614                }
10615            }
10616        }
10617        return lastDoneReceivers;
10618    }
10619
10620    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10621        File file = getCalledPreBootReceiversFile();
10622        FileOutputStream fos = null;
10623        DataOutputStream dos = null;
10624        try {
10625            fos = new FileOutputStream(file);
10626            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10627            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10628            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10629            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10630            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10631            dos.writeInt(list.size());
10632            for (int i=0; i<list.size(); i++) {
10633                dos.writeUTF(list.get(i).getPackageName());
10634                dos.writeUTF(list.get(i).getClassName());
10635            }
10636        } catch (IOException e) {
10637            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10638            file.delete();
10639        } finally {
10640            FileUtils.sync(fos);
10641            if (dos != null) {
10642                try {
10643                    dos.close();
10644                } catch (IOException e) {
10645                    // TODO Auto-generated catch block
10646                    e.printStackTrace();
10647                }
10648            }
10649        }
10650    }
10651
10652    final class PreBootContinuation extends IIntentReceiver.Stub {
10653        final Intent intent;
10654        final Runnable onFinishCallback;
10655        final ArrayList<ComponentName> doneReceivers;
10656        final List<ResolveInfo> ris;
10657        final int[] users;
10658        int lastRi = -1;
10659        int curRi = 0;
10660        int curUser = 0;
10661
10662        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
10663                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
10664            intent = _intent;
10665            onFinishCallback = _onFinishCallback;
10666            doneReceivers = _doneReceivers;
10667            ris = _ris;
10668            users = _users;
10669        }
10670
10671        void go() {
10672            if (lastRi != curRi) {
10673                ActivityInfo ai = ris.get(curRi).activityInfo;
10674                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10675                intent.setComponent(comp);
10676                doneReceivers.add(comp);
10677                lastRi = curRi;
10678                CharSequence label = ai.loadLabel(mContext.getPackageManager());
10679                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
10680            }
10681            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
10682                    + " for user " + users[curUser]);
10683            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
10684            broadcastIntentLocked(null, null, intent, null, this,
10685                    0, null, null, null, AppOpsManager.OP_NONE,
10686                    true, false, MY_PID, Process.SYSTEM_UID,
10687                    users[curUser]);
10688        }
10689
10690        public void performReceive(Intent intent, int resultCode,
10691                String data, Bundle extras, boolean ordered,
10692                boolean sticky, int sendingUser) {
10693            curUser++;
10694            if (curUser >= users.length) {
10695                curUser = 0;
10696                curRi++;
10697                if (curRi >= ris.size()) {
10698                    // All done sending broadcasts!
10699                    if (onFinishCallback != null) {
10700                        // The raw IIntentReceiver interface is called
10701                        // with the AM lock held, so redispatch to
10702                        // execute our code without the lock.
10703                        mHandler.post(onFinishCallback);
10704                    }
10705                    return;
10706                }
10707            }
10708            go();
10709        }
10710    }
10711
10712    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10713            ArrayList<ComponentName> doneReceivers, int userId) {
10714        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10715        List<ResolveInfo> ris = null;
10716        try {
10717            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10718                    intent, null, 0, userId);
10719        } catch (RemoteException e) {
10720        }
10721        if (ris == null) {
10722            return false;
10723        }
10724        for (int i=ris.size()-1; i>=0; i--) {
10725            if ((ris.get(i).activityInfo.applicationInfo.flags
10726                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
10727                ris.remove(i);
10728            }
10729        }
10730        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10731
10732        // For User 0, load the version number. When delivering to a new user, deliver
10733        // to all receivers.
10734        if (userId == UserHandle.USER_OWNER) {
10735            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10736            for (int i=0; i<ris.size(); i++) {
10737                ActivityInfo ai = ris.get(i).activityInfo;
10738                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10739                if (false && lastDoneReceivers.contains(comp)) {
10740                    // We already did the pre boot receiver for this app with the current
10741                    // platform version, so don't do it again...
10742                    ris.remove(i);
10743                    i--;
10744                    // ...however, do keep it as one that has been done, so we don't
10745                    // forget about it when rewriting the file of last done receivers.
10746                    doneReceivers.add(comp);
10747                }
10748            }
10749        }
10750
10751        if (ris.size() <= 0) {
10752            return false;
10753        }
10754
10755        // If primary user, send broadcast to all available users, else just to userId
10756        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10757                : new int[] { userId };
10758        if (users.length <= 0) {
10759            return false;
10760        }
10761
10762        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
10763                ris, users);
10764        cont.go();
10765        return true;
10766    }
10767
10768    public void systemReady(final Runnable goingCallback) {
10769        synchronized(this) {
10770            if (mSystemReady) {
10771                // If we're done calling all the receivers, run the next "boot phase" passed in
10772                // by the SystemServer
10773                if (goingCallback != null) {
10774                    goingCallback.run();
10775                }
10776                return;
10777            }
10778
10779            // Make sure we have the current profile info, since it is needed for
10780            // security checks.
10781            updateCurrentProfileIdsLocked();
10782
10783            mRecentTasks.clear();
10784            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
10785            mTaskPersister.restoreTasksFromOtherDeviceLocked();
10786            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
10787            mTaskPersister.startPersisting();
10788
10789            // Check to see if there are any update receivers to run.
10790            if (!mDidUpdate) {
10791                if (mWaitingUpdate) {
10792                    return;
10793                }
10794                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10795                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10796                    public void run() {
10797                        synchronized (ActivityManagerService.this) {
10798                            mDidUpdate = true;
10799                        }
10800                        showBootMessage(mContext.getText(
10801                                R.string.android_upgrading_complete),
10802                                false);
10803                        writeLastDonePreBootReceivers(doneReceivers);
10804                        systemReady(goingCallback);
10805                    }
10806                }, doneReceivers, UserHandle.USER_OWNER);
10807
10808                if (mWaitingUpdate) {
10809                    return;
10810                }
10811                mDidUpdate = true;
10812            }
10813
10814            mAppOpsService.systemReady();
10815            mSystemReady = true;
10816        }
10817
10818        ArrayList<ProcessRecord> procsToKill = null;
10819        synchronized(mPidsSelfLocked) {
10820            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10821                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10822                if (!isAllowedWhileBooting(proc.info)){
10823                    if (procsToKill == null) {
10824                        procsToKill = new ArrayList<ProcessRecord>();
10825                    }
10826                    procsToKill.add(proc);
10827                }
10828            }
10829        }
10830
10831        synchronized(this) {
10832            if (procsToKill != null) {
10833                for (int i=procsToKill.size()-1; i>=0; i--) {
10834                    ProcessRecord proc = procsToKill.get(i);
10835                    Slog.i(TAG, "Removing system update proc: " + proc);
10836                    removeProcessLocked(proc, true, false, "system update done");
10837                }
10838            }
10839
10840            // Now that we have cleaned up any update processes, we
10841            // are ready to start launching real processes and know that
10842            // we won't trample on them any more.
10843            mProcessesReady = true;
10844        }
10845
10846        Slog.i(TAG, "System now ready");
10847        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10848            SystemClock.uptimeMillis());
10849
10850        synchronized(this) {
10851            // Make sure we have no pre-ready processes sitting around.
10852
10853            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10854                ResolveInfo ri = mContext.getPackageManager()
10855                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10856                                STOCK_PM_FLAGS);
10857                CharSequence errorMsg = null;
10858                if (ri != null) {
10859                    ActivityInfo ai = ri.activityInfo;
10860                    ApplicationInfo app = ai.applicationInfo;
10861                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10862                        mTopAction = Intent.ACTION_FACTORY_TEST;
10863                        mTopData = null;
10864                        mTopComponent = new ComponentName(app.packageName,
10865                                ai.name);
10866                    } else {
10867                        errorMsg = mContext.getResources().getText(
10868                                com.android.internal.R.string.factorytest_not_system);
10869                    }
10870                } else {
10871                    errorMsg = mContext.getResources().getText(
10872                            com.android.internal.R.string.factorytest_no_action);
10873                }
10874                if (errorMsg != null) {
10875                    mTopAction = null;
10876                    mTopData = null;
10877                    mTopComponent = null;
10878                    Message msg = Message.obtain();
10879                    msg.what = SHOW_FACTORY_ERROR_MSG;
10880                    msg.getData().putCharSequence("msg", errorMsg);
10881                    mHandler.sendMessage(msg);
10882                }
10883            }
10884        }
10885
10886        retrieveSettings();
10887        loadResourcesOnSystemReady();
10888
10889        synchronized (this) {
10890            readGrantedUriPermissionsLocked();
10891        }
10892
10893        if (goingCallback != null) goingCallback.run();
10894
10895        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10896                Integer.toString(mCurrentUserId), mCurrentUserId);
10897        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10898                Integer.toString(mCurrentUserId), mCurrentUserId);
10899        mSystemServiceManager.startUser(mCurrentUserId);
10900
10901        synchronized (this) {
10902            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10903                try {
10904                    List apps = AppGlobals.getPackageManager().
10905                        getPersistentApplications(STOCK_PM_FLAGS);
10906                    if (apps != null) {
10907                        int N = apps.size();
10908                        int i;
10909                        for (i=0; i<N; i++) {
10910                            ApplicationInfo info
10911                                = (ApplicationInfo)apps.get(i);
10912                            if (info != null &&
10913                                    !info.packageName.equals("android")) {
10914                                addAppLocked(info, false, null /* ABI override */);
10915                            }
10916                        }
10917                    }
10918                } catch (RemoteException ex) {
10919                    // pm is in same process, this will never happen.
10920                }
10921            }
10922
10923            // Start up initial activity.
10924            mBooting = true;
10925            startHomeActivityLocked(mCurrentUserId, "systemReady");
10926
10927            try {
10928                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10929                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
10930                            + " data partition or your device will be unstable.");
10931                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
10932                }
10933            } catch (RemoteException e) {
10934            }
10935
10936            if (!Build.isBuildConsistent()) {
10937                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
10938                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
10939            }
10940
10941            long ident = Binder.clearCallingIdentity();
10942            try {
10943                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10944                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10945                        | Intent.FLAG_RECEIVER_FOREGROUND);
10946                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10947                broadcastIntentLocked(null, null, intent,
10948                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10949                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10950                intent = new Intent(Intent.ACTION_USER_STARTING);
10951                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10952                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10953                broadcastIntentLocked(null, null, intent,
10954                        null, new IIntentReceiver.Stub() {
10955                            @Override
10956                            public void performReceive(Intent intent, int resultCode, String data,
10957                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10958                                    throws RemoteException {
10959                            }
10960                        }, 0, null, null,
10961                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10962                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10963            } catch (Throwable t) {
10964                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10965            } finally {
10966                Binder.restoreCallingIdentity(ident);
10967            }
10968            mStackSupervisor.resumeTopActivitiesLocked();
10969            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10970        }
10971    }
10972
10973    private boolean makeAppCrashingLocked(ProcessRecord app,
10974            String shortMsg, String longMsg, String stackTrace) {
10975        app.crashing = true;
10976        app.crashingReport = generateProcessError(app,
10977                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10978        startAppProblemLocked(app);
10979        app.stopFreezingAllLocked();
10980        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
10981    }
10982
10983    private void makeAppNotRespondingLocked(ProcessRecord app,
10984            String activity, String shortMsg, String longMsg) {
10985        app.notResponding = true;
10986        app.notRespondingReport = generateProcessError(app,
10987                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10988                activity, shortMsg, longMsg, null);
10989        startAppProblemLocked(app);
10990        app.stopFreezingAllLocked();
10991    }
10992
10993    /**
10994     * Generate a process error record, suitable for attachment to a ProcessRecord.
10995     *
10996     * @param app The ProcessRecord in which the error occurred.
10997     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10998     *                      ActivityManager.AppErrorStateInfo
10999     * @param activity The activity associated with the crash, if known.
11000     * @param shortMsg Short message describing the crash.
11001     * @param longMsg Long message describing the crash.
11002     * @param stackTrace Full crash stack trace, may be null.
11003     *
11004     * @return Returns a fully-formed AppErrorStateInfo record.
11005     */
11006    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11007            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11008        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11009
11010        report.condition = condition;
11011        report.processName = app.processName;
11012        report.pid = app.pid;
11013        report.uid = app.info.uid;
11014        report.tag = activity;
11015        report.shortMsg = shortMsg;
11016        report.longMsg = longMsg;
11017        report.stackTrace = stackTrace;
11018
11019        return report;
11020    }
11021
11022    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11023        synchronized (this) {
11024            app.crashing = false;
11025            app.crashingReport = null;
11026            app.notResponding = false;
11027            app.notRespondingReport = null;
11028            if (app.anrDialog == fromDialog) {
11029                app.anrDialog = null;
11030            }
11031            if (app.waitDialog == fromDialog) {
11032                app.waitDialog = null;
11033            }
11034            if (app.pid > 0 && app.pid != MY_PID) {
11035                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11036                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11037                app.kill("user request after error", true);
11038            }
11039        }
11040    }
11041
11042    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11043            String shortMsg, String longMsg, String stackTrace) {
11044        long now = SystemClock.uptimeMillis();
11045
11046        Long crashTime;
11047        if (!app.isolated) {
11048            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11049        } else {
11050            crashTime = null;
11051        }
11052        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11053            // This process loses!
11054            Slog.w(TAG, "Process " + app.info.processName
11055                    + " has crashed too many times: killing!");
11056            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11057                    app.userId, app.info.processName, app.uid);
11058            mStackSupervisor.handleAppCrashLocked(app);
11059            if (!app.persistent) {
11060                // We don't want to start this process again until the user
11061                // explicitly does so...  but for persistent process, we really
11062                // need to keep it running.  If a persistent process is actually
11063                // repeatedly crashing, then badness for everyone.
11064                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11065                        app.info.processName);
11066                if (!app.isolated) {
11067                    // XXX We don't have a way to mark isolated processes
11068                    // as bad, since they don't have a peristent identity.
11069                    mBadProcesses.put(app.info.processName, app.uid,
11070                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11071                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11072                }
11073                app.bad = true;
11074                app.removed = true;
11075                // Don't let services in this process be restarted and potentially
11076                // annoy the user repeatedly.  Unless it is persistent, since those
11077                // processes run critical code.
11078                removeProcessLocked(app, false, false, "crash");
11079                mStackSupervisor.resumeTopActivitiesLocked();
11080                return false;
11081            }
11082            mStackSupervisor.resumeTopActivitiesLocked();
11083        } else {
11084            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11085        }
11086
11087        // Bump up the crash count of any services currently running in the proc.
11088        for (int i=app.services.size()-1; i>=0; i--) {
11089            // Any services running in the application need to be placed
11090            // back in the pending list.
11091            ServiceRecord sr = app.services.valueAt(i);
11092            sr.crashCount++;
11093        }
11094
11095        // If the crashing process is what we consider to be the "home process" and it has been
11096        // replaced by a third-party app, clear the package preferred activities from packages
11097        // with a home activity running in the process to prevent a repeatedly crashing app
11098        // from blocking the user to manually clear the list.
11099        final ArrayList<ActivityRecord> activities = app.activities;
11100        if (app == mHomeProcess && activities.size() > 0
11101                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11102            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11103                final ActivityRecord r = activities.get(activityNdx);
11104                if (r.isHomeActivity()) {
11105                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11106                    try {
11107                        ActivityThread.getPackageManager()
11108                                .clearPackagePreferredActivities(r.packageName);
11109                    } catch (RemoteException c) {
11110                        // pm is in same process, this will never happen.
11111                    }
11112                }
11113            }
11114        }
11115
11116        if (!app.isolated) {
11117            // XXX Can't keep track of crash times for isolated processes,
11118            // because they don't have a perisistent identity.
11119            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11120        }
11121
11122        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11123        return true;
11124    }
11125
11126    void startAppProblemLocked(ProcessRecord app) {
11127        // If this app is not running under the current user, then we
11128        // can't give it a report button because that would require
11129        // launching the report UI under a different user.
11130        app.errorReportReceiver = null;
11131
11132        for (int userId : mCurrentProfileIds) {
11133            if (app.userId == userId) {
11134                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11135                        mContext, app.info.packageName, app.info.flags);
11136            }
11137        }
11138        skipCurrentReceiverLocked(app);
11139    }
11140
11141    void skipCurrentReceiverLocked(ProcessRecord app) {
11142        for (BroadcastQueue queue : mBroadcastQueues) {
11143            queue.skipCurrentReceiverLocked(app);
11144        }
11145    }
11146
11147    /**
11148     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11149     * The application process will exit immediately after this call returns.
11150     * @param app object of the crashing app, null for the system server
11151     * @param crashInfo describing the exception
11152     */
11153    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11154        ProcessRecord r = findAppProcess(app, "Crash");
11155        final String processName = app == null ? "system_server"
11156                : (r == null ? "unknown" : r.processName);
11157
11158        handleApplicationCrashInner("crash", r, processName, crashInfo);
11159    }
11160
11161    /* Native crash reporting uses this inner version because it needs to be somewhat
11162     * decoupled from the AM-managed cleanup lifecycle
11163     */
11164    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11165            ApplicationErrorReport.CrashInfo crashInfo) {
11166        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11167                UserHandle.getUserId(Binder.getCallingUid()), processName,
11168                r == null ? -1 : r.info.flags,
11169                crashInfo.exceptionClassName,
11170                crashInfo.exceptionMessage,
11171                crashInfo.throwFileName,
11172                crashInfo.throwLineNumber);
11173
11174        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11175
11176        crashApplication(r, crashInfo);
11177    }
11178
11179    public void handleApplicationStrictModeViolation(
11180            IBinder app,
11181            int violationMask,
11182            StrictMode.ViolationInfo info) {
11183        ProcessRecord r = findAppProcess(app, "StrictMode");
11184        if (r == null) {
11185            return;
11186        }
11187
11188        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11189            Integer stackFingerprint = info.hashCode();
11190            boolean logIt = true;
11191            synchronized (mAlreadyLoggedViolatedStacks) {
11192                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11193                    logIt = false;
11194                    // TODO: sub-sample into EventLog for these, with
11195                    // the info.durationMillis?  Then we'd get
11196                    // the relative pain numbers, without logging all
11197                    // the stack traces repeatedly.  We'd want to do
11198                    // likewise in the client code, which also does
11199                    // dup suppression, before the Binder call.
11200                } else {
11201                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11202                        mAlreadyLoggedViolatedStacks.clear();
11203                    }
11204                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11205                }
11206            }
11207            if (logIt) {
11208                logStrictModeViolationToDropBox(r, info);
11209            }
11210        }
11211
11212        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11213            AppErrorResult result = new AppErrorResult();
11214            synchronized (this) {
11215                final long origId = Binder.clearCallingIdentity();
11216
11217                Message msg = Message.obtain();
11218                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11219                HashMap<String, Object> data = new HashMap<String, Object>();
11220                data.put("result", result);
11221                data.put("app", r);
11222                data.put("violationMask", violationMask);
11223                data.put("info", info);
11224                msg.obj = data;
11225                mHandler.sendMessage(msg);
11226
11227                Binder.restoreCallingIdentity(origId);
11228            }
11229            int res = result.get();
11230            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11231        }
11232    }
11233
11234    // Depending on the policy in effect, there could be a bunch of
11235    // these in quick succession so we try to batch these together to
11236    // minimize disk writes, number of dropbox entries, and maximize
11237    // compression, by having more fewer, larger records.
11238    private void logStrictModeViolationToDropBox(
11239            ProcessRecord process,
11240            StrictMode.ViolationInfo info) {
11241        if (info == null) {
11242            return;
11243        }
11244        final boolean isSystemApp = process == null ||
11245                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11246                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11247        final String processName = process == null ? "unknown" : process.processName;
11248        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11249        final DropBoxManager dbox = (DropBoxManager)
11250                mContext.getSystemService(Context.DROPBOX_SERVICE);
11251
11252        // Exit early if the dropbox isn't configured to accept this report type.
11253        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11254
11255        boolean bufferWasEmpty;
11256        boolean needsFlush;
11257        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11258        synchronized (sb) {
11259            bufferWasEmpty = sb.length() == 0;
11260            appendDropBoxProcessHeaders(process, processName, sb);
11261            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11262            sb.append("System-App: ").append(isSystemApp).append("\n");
11263            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11264            if (info.violationNumThisLoop != 0) {
11265                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11266            }
11267            if (info.numAnimationsRunning != 0) {
11268                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11269            }
11270            if (info.broadcastIntentAction != null) {
11271                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11272            }
11273            if (info.durationMillis != -1) {
11274                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11275            }
11276            if (info.numInstances != -1) {
11277                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11278            }
11279            if (info.tags != null) {
11280                for (String tag : info.tags) {
11281                    sb.append("Span-Tag: ").append(tag).append("\n");
11282                }
11283            }
11284            sb.append("\n");
11285            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11286                sb.append(info.crashInfo.stackTrace);
11287                sb.append("\n");
11288            }
11289            if (info.message != null) {
11290                sb.append(info.message);
11291                sb.append("\n");
11292            }
11293
11294            // Only buffer up to ~64k.  Various logging bits truncate
11295            // things at 128k.
11296            needsFlush = (sb.length() > 64 * 1024);
11297        }
11298
11299        // Flush immediately if the buffer's grown too large, or this
11300        // is a non-system app.  Non-system apps are isolated with a
11301        // different tag & policy and not batched.
11302        //
11303        // Batching is useful during internal testing with
11304        // StrictMode settings turned up high.  Without batching,
11305        // thousands of separate files could be created on boot.
11306        if (!isSystemApp || needsFlush) {
11307            new Thread("Error dump: " + dropboxTag) {
11308                @Override
11309                public void run() {
11310                    String report;
11311                    synchronized (sb) {
11312                        report = sb.toString();
11313                        sb.delete(0, sb.length());
11314                        sb.trimToSize();
11315                    }
11316                    if (report.length() != 0) {
11317                        dbox.addText(dropboxTag, report);
11318                    }
11319                }
11320            }.start();
11321            return;
11322        }
11323
11324        // System app batching:
11325        if (!bufferWasEmpty) {
11326            // An existing dropbox-writing thread is outstanding, so
11327            // we don't need to start it up.  The existing thread will
11328            // catch the buffer appends we just did.
11329            return;
11330        }
11331
11332        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11333        // (After this point, we shouldn't access AMS internal data structures.)
11334        new Thread("Error dump: " + dropboxTag) {
11335            @Override
11336            public void run() {
11337                // 5 second sleep to let stacks arrive and be batched together
11338                try {
11339                    Thread.sleep(5000);  // 5 seconds
11340                } catch (InterruptedException e) {}
11341
11342                String errorReport;
11343                synchronized (mStrictModeBuffer) {
11344                    errorReport = mStrictModeBuffer.toString();
11345                    if (errorReport.length() == 0) {
11346                        return;
11347                    }
11348                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11349                    mStrictModeBuffer.trimToSize();
11350                }
11351                dbox.addText(dropboxTag, errorReport);
11352            }
11353        }.start();
11354    }
11355
11356    /**
11357     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11358     * @param app object of the crashing app, null for the system server
11359     * @param tag reported by the caller
11360     * @param system whether this wtf is coming from the system
11361     * @param crashInfo describing the context of the error
11362     * @return true if the process should exit immediately (WTF is fatal)
11363     */
11364    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11365            final ApplicationErrorReport.CrashInfo crashInfo) {
11366        final int callingUid = Binder.getCallingUid();
11367        final int callingPid = Binder.getCallingPid();
11368
11369        if (system) {
11370            // If this is coming from the system, we could very well have low-level
11371            // system locks held, so we want to do this all asynchronously.  And we
11372            // never want this to become fatal, so there is that too.
11373            mHandler.post(new Runnable() {
11374                @Override public void run() {
11375                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11376                }
11377            });
11378            return false;
11379        }
11380
11381        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11382                crashInfo);
11383
11384        if (r != null && r.pid != Process.myPid() &&
11385                Settings.Global.getInt(mContext.getContentResolver(),
11386                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11387            crashApplication(r, crashInfo);
11388            return true;
11389        } else {
11390            return false;
11391        }
11392    }
11393
11394    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11395            final ApplicationErrorReport.CrashInfo crashInfo) {
11396        final ProcessRecord r = findAppProcess(app, "WTF");
11397        final String processName = app == null ? "system_server"
11398                : (r == null ? "unknown" : r.processName);
11399
11400        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11401                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11402
11403        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11404
11405        return r;
11406    }
11407
11408    /**
11409     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11410     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11411     */
11412    private ProcessRecord findAppProcess(IBinder app, String reason) {
11413        if (app == null) {
11414            return null;
11415        }
11416
11417        synchronized (this) {
11418            final int NP = mProcessNames.getMap().size();
11419            for (int ip=0; ip<NP; ip++) {
11420                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11421                final int NA = apps.size();
11422                for (int ia=0; ia<NA; ia++) {
11423                    ProcessRecord p = apps.valueAt(ia);
11424                    if (p.thread != null && p.thread.asBinder() == app) {
11425                        return p;
11426                    }
11427                }
11428            }
11429
11430            Slog.w(TAG, "Can't find mystery application for " + reason
11431                    + " from pid=" + Binder.getCallingPid()
11432                    + " uid=" + Binder.getCallingUid() + ": " + app);
11433            return null;
11434        }
11435    }
11436
11437    /**
11438     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11439     * to append various headers to the dropbox log text.
11440     */
11441    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11442            StringBuilder sb) {
11443        // Watchdog thread ends up invoking this function (with
11444        // a null ProcessRecord) to add the stack file to dropbox.
11445        // Do not acquire a lock on this (am) in such cases, as it
11446        // could cause a potential deadlock, if and when watchdog
11447        // is invoked due to unavailability of lock on am and it
11448        // would prevent watchdog from killing system_server.
11449        if (process == null) {
11450            sb.append("Process: ").append(processName).append("\n");
11451            return;
11452        }
11453        // Note: ProcessRecord 'process' is guarded by the service
11454        // instance.  (notably process.pkgList, which could otherwise change
11455        // concurrently during execution of this method)
11456        synchronized (this) {
11457            sb.append("Process: ").append(processName).append("\n");
11458            int flags = process.info.flags;
11459            IPackageManager pm = AppGlobals.getPackageManager();
11460            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11461            for (int ip=0; ip<process.pkgList.size(); ip++) {
11462                String pkg = process.pkgList.keyAt(ip);
11463                sb.append("Package: ").append(pkg);
11464                try {
11465                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11466                    if (pi != null) {
11467                        sb.append(" v").append(pi.versionCode);
11468                        if (pi.versionName != null) {
11469                            sb.append(" (").append(pi.versionName).append(")");
11470                        }
11471                    }
11472                } catch (RemoteException e) {
11473                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11474                }
11475                sb.append("\n");
11476            }
11477        }
11478    }
11479
11480    private static String processClass(ProcessRecord process) {
11481        if (process == null || process.pid == MY_PID) {
11482            return "system_server";
11483        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11484            return "system_app";
11485        } else {
11486            return "data_app";
11487        }
11488    }
11489
11490    /**
11491     * Write a description of an error (crash, WTF, ANR) to the drop box.
11492     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11493     * @param process which caused the error, null means the system server
11494     * @param activity which triggered the error, null if unknown
11495     * @param parent activity related to the error, null if unknown
11496     * @param subject line related to the error, null if absent
11497     * @param report in long form describing the error, null if absent
11498     * @param logFile to include in the report, null if none
11499     * @param crashInfo giving an application stack trace, null if absent
11500     */
11501    public void addErrorToDropBox(String eventType,
11502            ProcessRecord process, String processName, ActivityRecord activity,
11503            ActivityRecord parent, String subject,
11504            final String report, final File logFile,
11505            final ApplicationErrorReport.CrashInfo crashInfo) {
11506        // NOTE -- this must never acquire the ActivityManagerService lock,
11507        // otherwise the watchdog may be prevented from resetting the system.
11508
11509        final String dropboxTag = processClass(process) + "_" + eventType;
11510        final DropBoxManager dbox = (DropBoxManager)
11511                mContext.getSystemService(Context.DROPBOX_SERVICE);
11512
11513        // Exit early if the dropbox isn't configured to accept this report type.
11514        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11515
11516        final StringBuilder sb = new StringBuilder(1024);
11517        appendDropBoxProcessHeaders(process, processName, sb);
11518        if (activity != null) {
11519            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11520        }
11521        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11522            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11523        }
11524        if (parent != null && parent != activity) {
11525            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11526        }
11527        if (subject != null) {
11528            sb.append("Subject: ").append(subject).append("\n");
11529        }
11530        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11531        if (Debug.isDebuggerConnected()) {
11532            sb.append("Debugger: Connected\n");
11533        }
11534        sb.append("\n");
11535
11536        // Do the rest in a worker thread to avoid blocking the caller on I/O
11537        // (After this point, we shouldn't access AMS internal data structures.)
11538        Thread worker = new Thread("Error dump: " + dropboxTag) {
11539            @Override
11540            public void run() {
11541                if (report != null) {
11542                    sb.append(report);
11543                }
11544                if (logFile != null) {
11545                    try {
11546                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11547                                    "\n\n[[TRUNCATED]]"));
11548                    } catch (IOException e) {
11549                        Slog.e(TAG, "Error reading " + logFile, e);
11550                    }
11551                }
11552                if (crashInfo != null && crashInfo.stackTrace != null) {
11553                    sb.append(crashInfo.stackTrace);
11554                }
11555
11556                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11557                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11558                if (lines > 0) {
11559                    sb.append("\n");
11560
11561                    // Merge several logcat streams, and take the last N lines
11562                    InputStreamReader input = null;
11563                    try {
11564                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11565                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11566                                "-b", "crash",
11567                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11568
11569                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11570                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11571                        input = new InputStreamReader(logcat.getInputStream());
11572
11573                        int num;
11574                        char[] buf = new char[8192];
11575                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11576                    } catch (IOException e) {
11577                        Slog.e(TAG, "Error running logcat", e);
11578                    } finally {
11579                        if (input != null) try { input.close(); } catch (IOException e) {}
11580                    }
11581                }
11582
11583                dbox.addText(dropboxTag, sb.toString());
11584            }
11585        };
11586
11587        if (process == null) {
11588            // If process is null, we are being called from some internal code
11589            // and may be about to die -- run this synchronously.
11590            worker.run();
11591        } else {
11592            worker.start();
11593        }
11594    }
11595
11596    /**
11597     * Bring up the "unexpected error" dialog box for a crashing app.
11598     * Deal with edge cases (intercepts from instrumented applications,
11599     * ActivityController, error intent receivers, that sort of thing).
11600     * @param r the application crashing
11601     * @param crashInfo describing the failure
11602     */
11603    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11604        long timeMillis = System.currentTimeMillis();
11605        String shortMsg = crashInfo.exceptionClassName;
11606        String longMsg = crashInfo.exceptionMessage;
11607        String stackTrace = crashInfo.stackTrace;
11608        if (shortMsg != null && longMsg != null) {
11609            longMsg = shortMsg + ": " + longMsg;
11610        } else if (shortMsg != null) {
11611            longMsg = shortMsg;
11612        }
11613
11614        AppErrorResult result = new AppErrorResult();
11615        synchronized (this) {
11616            if (mController != null) {
11617                try {
11618                    String name = r != null ? r.processName : null;
11619                    int pid = r != null ? r.pid : Binder.getCallingPid();
11620                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11621                    if (!mController.appCrashed(name, pid,
11622                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11623                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11624                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11625                            Slog.w(TAG, "Skip killing native crashed app " + name
11626                                    + "(" + pid + ") during testing");
11627                        } else {
11628                            Slog.w(TAG, "Force-killing crashed app " + name
11629                                    + " at watcher's request");
11630                            if (r != null) {
11631                                r.kill("crash", true);
11632                            } else {
11633                                // Huh.
11634                                Process.killProcess(pid);
11635                                Process.killProcessGroup(uid, pid);
11636                            }
11637                        }
11638                        return;
11639                    }
11640                } catch (RemoteException e) {
11641                    mController = null;
11642                    Watchdog.getInstance().setActivityController(null);
11643                }
11644            }
11645
11646            final long origId = Binder.clearCallingIdentity();
11647
11648            // If this process is running instrumentation, finish it.
11649            if (r != null && r.instrumentationClass != null) {
11650                Slog.w(TAG, "Error in app " + r.processName
11651                      + " running instrumentation " + r.instrumentationClass + ":");
11652                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11653                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11654                Bundle info = new Bundle();
11655                info.putString("shortMsg", shortMsg);
11656                info.putString("longMsg", longMsg);
11657                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11658                Binder.restoreCallingIdentity(origId);
11659                return;
11660            }
11661
11662            // Log crash in battery stats.
11663            if (r != null) {
11664                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11665            }
11666
11667            // If we can't identify the process or it's already exceeded its crash quota,
11668            // quit right away without showing a crash dialog.
11669            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11670                Binder.restoreCallingIdentity(origId);
11671                return;
11672            }
11673
11674            Message msg = Message.obtain();
11675            msg.what = SHOW_ERROR_MSG;
11676            HashMap data = new HashMap();
11677            data.put("result", result);
11678            data.put("app", r);
11679            msg.obj = data;
11680            mHandler.sendMessage(msg);
11681
11682            Binder.restoreCallingIdentity(origId);
11683        }
11684
11685        int res = result.get();
11686
11687        Intent appErrorIntent = null;
11688        synchronized (this) {
11689            if (r != null && !r.isolated) {
11690                // XXX Can't keep track of crash time for isolated processes,
11691                // since they don't have a persistent identity.
11692                mProcessCrashTimes.put(r.info.processName, r.uid,
11693                        SystemClock.uptimeMillis());
11694            }
11695            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11696                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11697            }
11698        }
11699
11700        if (appErrorIntent != null) {
11701            try {
11702                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11703            } catch (ActivityNotFoundException e) {
11704                Slog.w(TAG, "bug report receiver dissappeared", e);
11705            }
11706        }
11707    }
11708
11709    Intent createAppErrorIntentLocked(ProcessRecord r,
11710            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11711        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11712        if (report == null) {
11713            return null;
11714        }
11715        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11716        result.setComponent(r.errorReportReceiver);
11717        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11718        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11719        return result;
11720    }
11721
11722    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11723            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11724        if (r.errorReportReceiver == null) {
11725            return null;
11726        }
11727
11728        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11729            return null;
11730        }
11731
11732        ApplicationErrorReport report = new ApplicationErrorReport();
11733        report.packageName = r.info.packageName;
11734        report.installerPackageName = r.errorReportReceiver.getPackageName();
11735        report.processName = r.processName;
11736        report.time = timeMillis;
11737        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11738
11739        if (r.crashing || r.forceCrashReport) {
11740            report.type = ApplicationErrorReport.TYPE_CRASH;
11741            report.crashInfo = crashInfo;
11742        } else if (r.notResponding) {
11743            report.type = ApplicationErrorReport.TYPE_ANR;
11744            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11745
11746            report.anrInfo.activity = r.notRespondingReport.tag;
11747            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11748            report.anrInfo.info = r.notRespondingReport.longMsg;
11749        }
11750
11751        return report;
11752    }
11753
11754    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11755        enforceNotIsolatedCaller("getProcessesInErrorState");
11756        // assume our apps are happy - lazy create the list
11757        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11758
11759        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11760                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11761        int userId = UserHandle.getUserId(Binder.getCallingUid());
11762
11763        synchronized (this) {
11764
11765            // iterate across all processes
11766            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11767                ProcessRecord app = mLruProcesses.get(i);
11768                if (!allUsers && app.userId != userId) {
11769                    continue;
11770                }
11771                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11772                    // This one's in trouble, so we'll generate a report for it
11773                    // crashes are higher priority (in case there's a crash *and* an anr)
11774                    ActivityManager.ProcessErrorStateInfo report = null;
11775                    if (app.crashing) {
11776                        report = app.crashingReport;
11777                    } else if (app.notResponding) {
11778                        report = app.notRespondingReport;
11779                    }
11780
11781                    if (report != null) {
11782                        if (errList == null) {
11783                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11784                        }
11785                        errList.add(report);
11786                    } else {
11787                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11788                                " crashing = " + app.crashing +
11789                                " notResponding = " + app.notResponding);
11790                    }
11791                }
11792            }
11793        }
11794
11795        return errList;
11796    }
11797
11798    static int procStateToImportance(int procState, int memAdj,
11799            ActivityManager.RunningAppProcessInfo currApp) {
11800        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11801        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11802            currApp.lru = memAdj;
11803        } else {
11804            currApp.lru = 0;
11805        }
11806        return imp;
11807    }
11808
11809    private void fillInProcMemInfo(ProcessRecord app,
11810            ActivityManager.RunningAppProcessInfo outInfo) {
11811        outInfo.pid = app.pid;
11812        outInfo.uid = app.info.uid;
11813        if (mHeavyWeightProcess == app) {
11814            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11815        }
11816        if (app.persistent) {
11817            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11818        }
11819        if (app.activities.size() > 0) {
11820            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11821        }
11822        outInfo.lastTrimLevel = app.trimMemoryLevel;
11823        int adj = app.curAdj;
11824        int procState = app.curProcState;
11825        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11826        outInfo.importanceReasonCode = app.adjTypeCode;
11827        outInfo.processState = app.curProcState;
11828    }
11829
11830    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11831        enforceNotIsolatedCaller("getRunningAppProcesses");
11832        // Lazy instantiation of list
11833        List<ActivityManager.RunningAppProcessInfo> runList = null;
11834        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11835                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11836        int userId = UserHandle.getUserId(Binder.getCallingUid());
11837        synchronized (this) {
11838            // Iterate across all processes
11839            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11840                ProcessRecord app = mLruProcesses.get(i);
11841                if (!allUsers && app.userId != userId) {
11842                    continue;
11843                }
11844                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11845                    // Generate process state info for running application
11846                    ActivityManager.RunningAppProcessInfo currApp =
11847                        new ActivityManager.RunningAppProcessInfo(app.processName,
11848                                app.pid, app.getPackageList());
11849                    fillInProcMemInfo(app, currApp);
11850                    if (app.adjSource instanceof ProcessRecord) {
11851                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11852                        currApp.importanceReasonImportance =
11853                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11854                                        app.adjSourceProcState);
11855                    } else if (app.adjSource instanceof ActivityRecord) {
11856                        ActivityRecord r = (ActivityRecord)app.adjSource;
11857                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11858                    }
11859                    if (app.adjTarget instanceof ComponentName) {
11860                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11861                    }
11862                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11863                    //        + " lru=" + currApp.lru);
11864                    if (runList == null) {
11865                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11866                    }
11867                    runList.add(currApp);
11868                }
11869            }
11870        }
11871        return runList;
11872    }
11873
11874    public List<ApplicationInfo> getRunningExternalApplications() {
11875        enforceNotIsolatedCaller("getRunningExternalApplications");
11876        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11877        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11878        if (runningApps != null && runningApps.size() > 0) {
11879            Set<String> extList = new HashSet<String>();
11880            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11881                if (app.pkgList != null) {
11882                    for (String pkg : app.pkgList) {
11883                        extList.add(pkg);
11884                    }
11885                }
11886            }
11887            IPackageManager pm = AppGlobals.getPackageManager();
11888            for (String pkg : extList) {
11889                try {
11890                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11891                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11892                        retList.add(info);
11893                    }
11894                } catch (RemoteException e) {
11895                }
11896            }
11897        }
11898        return retList;
11899    }
11900
11901    @Override
11902    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11903        enforceNotIsolatedCaller("getMyMemoryState");
11904        synchronized (this) {
11905            ProcessRecord proc;
11906            synchronized (mPidsSelfLocked) {
11907                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11908            }
11909            fillInProcMemInfo(proc, outInfo);
11910        }
11911    }
11912
11913    @Override
11914    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11915        if (checkCallingPermission(android.Manifest.permission.DUMP)
11916                != PackageManager.PERMISSION_GRANTED) {
11917            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11918                    + Binder.getCallingPid()
11919                    + ", uid=" + Binder.getCallingUid()
11920                    + " without permission "
11921                    + android.Manifest.permission.DUMP);
11922            return;
11923        }
11924
11925        boolean dumpAll = false;
11926        boolean dumpClient = false;
11927        String dumpPackage = null;
11928
11929        int opti = 0;
11930        while (opti < args.length) {
11931            String opt = args[opti];
11932            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11933                break;
11934            }
11935            opti++;
11936            if ("-a".equals(opt)) {
11937                dumpAll = true;
11938            } else if ("-c".equals(opt)) {
11939                dumpClient = true;
11940            } else if ("-p".equals(opt)) {
11941                if (opti < args.length) {
11942                    dumpPackage = args[opti];
11943                    opti++;
11944                } else {
11945                    pw.println("Error: -p option requires package argument");
11946                    return;
11947                }
11948                dumpClient = true;
11949            } else if ("-h".equals(opt)) {
11950                pw.println("Activity manager dump options:");
11951                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
11952                pw.println("  cmd may be one of:");
11953                pw.println("    a[ctivities]: activity stack state");
11954                pw.println("    r[recents]: recent activities state");
11955                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11956                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11957                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11958                pw.println("    o[om]: out of memory management");
11959                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11960                pw.println("    provider [COMP_SPEC]: provider client-side state");
11961                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11962                pw.println("    as[sociations]: tracked app associations");
11963                pw.println("    service [COMP_SPEC]: service client-side state");
11964                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11965                pw.println("    all: dump all activities");
11966                pw.println("    top: dump the top activity");
11967                pw.println("    write: write all pending state to storage");
11968                pw.println("    track-associations: enable association tracking");
11969                pw.println("    untrack-associations: disable and clear association tracking");
11970                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11971                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11972                pw.println("    a partial substring in a component name, a");
11973                pw.println("    hex object identifier.");
11974                pw.println("  -a: include all available server state.");
11975                pw.println("  -c: include client state.");
11976                pw.println("  -p: limit output to given package.");
11977                return;
11978            } else {
11979                pw.println("Unknown argument: " + opt + "; use -h for help");
11980            }
11981        }
11982
11983        long origId = Binder.clearCallingIdentity();
11984        boolean more = false;
11985        // Is the caller requesting to dump a particular piece of data?
11986        if (opti < args.length) {
11987            String cmd = args[opti];
11988            opti++;
11989            if ("activities".equals(cmd) || "a".equals(cmd)) {
11990                synchronized (this) {
11991                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11992                }
11993            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11994                synchronized (this) {
11995                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
11996                }
11997            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11998                String[] newArgs;
11999                String name;
12000                if (opti >= args.length) {
12001                    name = null;
12002                    newArgs = EMPTY_STRING_ARRAY;
12003                } else {
12004                    dumpPackage = args[opti];
12005                    opti++;
12006                    newArgs = new String[args.length - opti];
12007                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12008                            args.length - opti);
12009                }
12010                synchronized (this) {
12011                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12012                }
12013            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12014                String[] newArgs;
12015                String name;
12016                if (opti >= args.length) {
12017                    name = null;
12018                    newArgs = EMPTY_STRING_ARRAY;
12019                } else {
12020                    dumpPackage = args[opti];
12021                    opti++;
12022                    newArgs = new String[args.length - opti];
12023                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12024                            args.length - opti);
12025                }
12026                synchronized (this) {
12027                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12028                }
12029            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12030                String[] newArgs;
12031                String name;
12032                if (opti >= args.length) {
12033                    name = null;
12034                    newArgs = EMPTY_STRING_ARRAY;
12035                } else {
12036                    dumpPackage = args[opti];
12037                    opti++;
12038                    newArgs = new String[args.length - opti];
12039                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12040                            args.length - opti);
12041                }
12042                synchronized (this) {
12043                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12044                }
12045            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12046                synchronized (this) {
12047                    dumpOomLocked(fd, pw, args, opti, true);
12048                }
12049            } else if ("provider".equals(cmd)) {
12050                String[] newArgs;
12051                String name;
12052                if (opti >= args.length) {
12053                    name = null;
12054                    newArgs = EMPTY_STRING_ARRAY;
12055                } else {
12056                    name = args[opti];
12057                    opti++;
12058                    newArgs = new String[args.length - opti];
12059                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12060                }
12061                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12062                    pw.println("No providers match: " + name);
12063                    pw.println("Use -h for help.");
12064                }
12065            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12066                synchronized (this) {
12067                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12068                }
12069            } else if ("service".equals(cmd)) {
12070                String[] newArgs;
12071                String name;
12072                if (opti >= args.length) {
12073                    name = null;
12074                    newArgs = EMPTY_STRING_ARRAY;
12075                } else {
12076                    name = args[opti];
12077                    opti++;
12078                    newArgs = new String[args.length - opti];
12079                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12080                            args.length - opti);
12081                }
12082                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12083                    pw.println("No services match: " + name);
12084                    pw.println("Use -h for help.");
12085                }
12086            } else if ("package".equals(cmd)) {
12087                String[] newArgs;
12088                if (opti >= args.length) {
12089                    pw.println("package: no package name specified");
12090                    pw.println("Use -h for help.");
12091                } else {
12092                    dumpPackage = args[opti];
12093                    opti++;
12094                    newArgs = new String[args.length - opti];
12095                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12096                            args.length - opti);
12097                    args = newArgs;
12098                    opti = 0;
12099                    more = true;
12100                }
12101            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12102                synchronized (this) {
12103                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12104                }
12105            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12106                synchronized (this) {
12107                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12108                }
12109            } else if ("write".equals(cmd)) {
12110                mTaskPersister.flush();
12111                pw.println("All tasks persisted.");
12112                return;
12113            } else if ("track-associations".equals(cmd)) {
12114                synchronized (this) {
12115                    if (!mTrackingAssociations) {
12116                        mTrackingAssociations = true;
12117                        pw.println("Association tracking started.");
12118                    } else {
12119                        pw.println("Association tracking already enabled.");
12120                    }
12121                }
12122                return;
12123            } else if ("untrack-associations".equals(cmd)) {
12124                synchronized (this) {
12125                    if (mTrackingAssociations) {
12126                        mTrackingAssociations = false;
12127                        mAssociations.clear();
12128                        pw.println("Association tracking stopped.");
12129                    } else {
12130                        pw.println("Association tracking not running.");
12131                    }
12132                }
12133                return;
12134            } else {
12135                // Dumping a single activity?
12136                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12137                    pw.println("Bad activity command, or no activities match: " + cmd);
12138                    pw.println("Use -h for help.");
12139                }
12140            }
12141            if (!more) {
12142                Binder.restoreCallingIdentity(origId);
12143                return;
12144            }
12145        }
12146
12147        // No piece of data specified, dump everything.
12148        synchronized (this) {
12149            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12150            pw.println();
12151            if (dumpAll) {
12152                pw.println("-------------------------------------------------------------------------------");
12153            }
12154            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12155            pw.println();
12156            if (dumpAll) {
12157                pw.println("-------------------------------------------------------------------------------");
12158            }
12159            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12160            pw.println();
12161            if (dumpAll) {
12162                pw.println("-------------------------------------------------------------------------------");
12163            }
12164            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12165            pw.println();
12166            if (dumpAll) {
12167                pw.println("-------------------------------------------------------------------------------");
12168            }
12169            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12170            pw.println();
12171            if (dumpAll) {
12172                pw.println("-------------------------------------------------------------------------------");
12173            }
12174            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12175            if (mAssociations.size() > 0) {
12176                pw.println();
12177                if (dumpAll) {
12178                    pw.println("-------------------------------------------------------------------------------");
12179                }
12180                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12181            }
12182            pw.println();
12183            if (dumpAll) {
12184                pw.println("-------------------------------------------------------------------------------");
12185            }
12186            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12187        }
12188        Binder.restoreCallingIdentity(origId);
12189    }
12190
12191    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12192            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12193        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12194
12195        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12196                dumpPackage);
12197        boolean needSep = printedAnything;
12198
12199        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12200                dumpPackage, needSep, "  mFocusedActivity: ");
12201        if (printed) {
12202            printedAnything = true;
12203            needSep = false;
12204        }
12205
12206        if (dumpPackage == null) {
12207            if (needSep) {
12208                pw.println();
12209            }
12210            needSep = true;
12211            printedAnything = true;
12212            mStackSupervisor.dump(pw, "  ");
12213        }
12214
12215        if (!printedAnything) {
12216            pw.println("  (nothing)");
12217        }
12218    }
12219
12220    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12221            int opti, boolean dumpAll, String dumpPackage) {
12222        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12223
12224        boolean printedAnything = false;
12225
12226        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12227            boolean printedHeader = false;
12228
12229            final int N = mRecentTasks.size();
12230            for (int i=0; i<N; i++) {
12231                TaskRecord tr = mRecentTasks.get(i);
12232                if (dumpPackage != null) {
12233                    if (tr.realActivity == null ||
12234                            !dumpPackage.equals(tr.realActivity)) {
12235                        continue;
12236                    }
12237                }
12238                if (!printedHeader) {
12239                    pw.println("  Recent tasks:");
12240                    printedHeader = true;
12241                    printedAnything = true;
12242                }
12243                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12244                        pw.println(tr);
12245                if (dumpAll) {
12246                    mRecentTasks.get(i).dump(pw, "    ");
12247                }
12248            }
12249        }
12250
12251        if (!printedAnything) {
12252            pw.println("  (nothing)");
12253        }
12254    }
12255
12256    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12257            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12258        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12259
12260        int dumpUid = 0;
12261        if (dumpPackage != null) {
12262            IPackageManager pm = AppGlobals.getPackageManager();
12263            try {
12264                dumpUid = pm.getPackageUid(dumpPackage, 0);
12265            } catch (RemoteException e) {
12266            }
12267        }
12268
12269        boolean printedAnything = false;
12270
12271        final long now = SystemClock.uptimeMillis();
12272
12273        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12274            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12275                    = mAssociations.valueAt(i1);
12276            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12277                SparseArray<ArrayMap<String, Association>> sourceUids
12278                        = targetComponents.valueAt(i2);
12279                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12280                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12281                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12282                        Association ass = sourceProcesses.valueAt(i4);
12283                        if (dumpPackage != null) {
12284                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12285                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12286                                continue;
12287                            }
12288                        }
12289                        printedAnything = true;
12290                        pw.print("  ");
12291                        pw.print(ass.mTargetProcess);
12292                        pw.print("/");
12293                        UserHandle.formatUid(pw, ass.mTargetUid);
12294                        pw.print(" <- ");
12295                        pw.print(ass.mSourceProcess);
12296                        pw.print("/");
12297                        UserHandle.formatUid(pw, ass.mSourceUid);
12298                        pw.println();
12299                        pw.print("    via ");
12300                        pw.print(ass.mTargetComponent.flattenToShortString());
12301                        pw.println();
12302                        pw.print("    ");
12303                        long dur = ass.mTime;
12304                        if (ass.mNesting > 0) {
12305                            dur += now - ass.mStartTime;
12306                        }
12307                        TimeUtils.formatDuration(dur, pw);
12308                        pw.print(" (");
12309                        pw.print(ass.mCount);
12310                        pw.println(" times)");
12311                        if (ass.mNesting > 0) {
12312                            pw.print("    ");
12313                            pw.print(" Currently active: ");
12314                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12315                            pw.println();
12316                        }
12317                    }
12318                }
12319            }
12320
12321        }
12322
12323        if (!printedAnything) {
12324            pw.println("  (nothing)");
12325        }
12326    }
12327
12328    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12329            int opti, boolean dumpAll, String dumpPackage) {
12330        boolean needSep = false;
12331        boolean printedAnything = false;
12332        int numPers = 0;
12333
12334        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12335
12336        if (dumpAll) {
12337            final int NP = mProcessNames.getMap().size();
12338            for (int ip=0; ip<NP; ip++) {
12339                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12340                final int NA = procs.size();
12341                for (int ia=0; ia<NA; ia++) {
12342                    ProcessRecord r = procs.valueAt(ia);
12343                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12344                        continue;
12345                    }
12346                    if (!needSep) {
12347                        pw.println("  All known processes:");
12348                        needSep = true;
12349                        printedAnything = true;
12350                    }
12351                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12352                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12353                        pw.print(" "); pw.println(r);
12354                    r.dump(pw, "    ");
12355                    if (r.persistent) {
12356                        numPers++;
12357                    }
12358                }
12359            }
12360        }
12361
12362        if (mIsolatedProcesses.size() > 0) {
12363            boolean printed = false;
12364            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12365                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12366                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12367                    continue;
12368                }
12369                if (!printed) {
12370                    if (needSep) {
12371                        pw.println();
12372                    }
12373                    pw.println("  Isolated process list (sorted by uid):");
12374                    printedAnything = true;
12375                    printed = true;
12376                    needSep = true;
12377                }
12378                pw.println(String.format("%sIsolated #%2d: %s",
12379                        "    ", i, r.toString()));
12380            }
12381        }
12382
12383        if (mLruProcesses.size() > 0) {
12384            if (needSep) {
12385                pw.println();
12386            }
12387            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12388                    pw.print(" total, non-act at ");
12389                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12390                    pw.print(", non-svc at ");
12391                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12392                    pw.println("):");
12393            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12394            needSep = true;
12395            printedAnything = true;
12396        }
12397
12398        if (dumpAll || dumpPackage != null) {
12399            synchronized (mPidsSelfLocked) {
12400                boolean printed = false;
12401                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12402                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12403                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12404                        continue;
12405                    }
12406                    if (!printed) {
12407                        if (needSep) pw.println();
12408                        needSep = true;
12409                        pw.println("  PID mappings:");
12410                        printed = true;
12411                        printedAnything = true;
12412                    }
12413                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12414                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12415                }
12416            }
12417        }
12418
12419        if (mForegroundProcesses.size() > 0) {
12420            synchronized (mPidsSelfLocked) {
12421                boolean printed = false;
12422                for (int i=0; i<mForegroundProcesses.size(); i++) {
12423                    ProcessRecord r = mPidsSelfLocked.get(
12424                            mForegroundProcesses.valueAt(i).pid);
12425                    if (dumpPackage != null && (r == null
12426                            || !r.pkgList.containsKey(dumpPackage))) {
12427                        continue;
12428                    }
12429                    if (!printed) {
12430                        if (needSep) pw.println();
12431                        needSep = true;
12432                        pw.println("  Foreground Processes:");
12433                        printed = true;
12434                        printedAnything = true;
12435                    }
12436                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12437                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12438                }
12439            }
12440        }
12441
12442        if (mPersistentStartingProcesses.size() > 0) {
12443            if (needSep) pw.println();
12444            needSep = true;
12445            printedAnything = true;
12446            pw.println("  Persisent processes that are starting:");
12447            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12448                    "Starting Norm", "Restarting PERS", dumpPackage);
12449        }
12450
12451        if (mRemovedProcesses.size() > 0) {
12452            if (needSep) pw.println();
12453            needSep = true;
12454            printedAnything = true;
12455            pw.println("  Processes that are being removed:");
12456            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12457                    "Removed Norm", "Removed PERS", dumpPackage);
12458        }
12459
12460        if (mProcessesOnHold.size() > 0) {
12461            if (needSep) pw.println();
12462            needSep = true;
12463            printedAnything = true;
12464            pw.println("  Processes that are on old until the system is ready:");
12465            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12466                    "OnHold Norm", "OnHold PERS", dumpPackage);
12467        }
12468
12469        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12470
12471        if (mProcessCrashTimes.getMap().size() > 0) {
12472            boolean printed = false;
12473            long now = SystemClock.uptimeMillis();
12474            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12475            final int NP = pmap.size();
12476            for (int ip=0; ip<NP; ip++) {
12477                String pname = pmap.keyAt(ip);
12478                SparseArray<Long> uids = pmap.valueAt(ip);
12479                final int N = uids.size();
12480                for (int i=0; i<N; i++) {
12481                    int puid = uids.keyAt(i);
12482                    ProcessRecord r = mProcessNames.get(pname, puid);
12483                    if (dumpPackage != null && (r == null
12484                            || !r.pkgList.containsKey(dumpPackage))) {
12485                        continue;
12486                    }
12487                    if (!printed) {
12488                        if (needSep) pw.println();
12489                        needSep = true;
12490                        pw.println("  Time since processes crashed:");
12491                        printed = true;
12492                        printedAnything = true;
12493                    }
12494                    pw.print("    Process "); pw.print(pname);
12495                            pw.print(" uid "); pw.print(puid);
12496                            pw.print(": last crashed ");
12497                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12498                            pw.println(" ago");
12499                }
12500            }
12501        }
12502
12503        if (mBadProcesses.getMap().size() > 0) {
12504            boolean printed = false;
12505            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12506            final int NP = pmap.size();
12507            for (int ip=0; ip<NP; ip++) {
12508                String pname = pmap.keyAt(ip);
12509                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12510                final int N = uids.size();
12511                for (int i=0; i<N; i++) {
12512                    int puid = uids.keyAt(i);
12513                    ProcessRecord r = mProcessNames.get(pname, puid);
12514                    if (dumpPackage != null && (r == null
12515                            || !r.pkgList.containsKey(dumpPackage))) {
12516                        continue;
12517                    }
12518                    if (!printed) {
12519                        if (needSep) pw.println();
12520                        needSep = true;
12521                        pw.println("  Bad processes:");
12522                        printedAnything = true;
12523                    }
12524                    BadProcessInfo info = uids.valueAt(i);
12525                    pw.print("    Bad process "); pw.print(pname);
12526                            pw.print(" uid "); pw.print(puid);
12527                            pw.print(": crashed at time "); pw.println(info.time);
12528                    if (info.shortMsg != null) {
12529                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12530                    }
12531                    if (info.longMsg != null) {
12532                        pw.print("      Long msg: "); pw.println(info.longMsg);
12533                    }
12534                    if (info.stack != null) {
12535                        pw.println("      Stack:");
12536                        int lastPos = 0;
12537                        for (int pos=0; pos<info.stack.length(); pos++) {
12538                            if (info.stack.charAt(pos) == '\n') {
12539                                pw.print("        ");
12540                                pw.write(info.stack, lastPos, pos-lastPos);
12541                                pw.println();
12542                                lastPos = pos+1;
12543                            }
12544                        }
12545                        if (lastPos < info.stack.length()) {
12546                            pw.print("        ");
12547                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12548                            pw.println();
12549                        }
12550                    }
12551                }
12552            }
12553        }
12554
12555        if (dumpPackage == null) {
12556            pw.println();
12557            needSep = false;
12558            pw.println("  mStartedUsers:");
12559            for (int i=0; i<mStartedUsers.size(); i++) {
12560                UserStartedState uss = mStartedUsers.valueAt(i);
12561                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12562                        pw.print(": "); uss.dump("", pw);
12563            }
12564            pw.print("  mStartedUserArray: [");
12565            for (int i=0; i<mStartedUserArray.length; i++) {
12566                if (i > 0) pw.print(", ");
12567                pw.print(mStartedUserArray[i]);
12568            }
12569            pw.println("]");
12570            pw.print("  mUserLru: [");
12571            for (int i=0; i<mUserLru.size(); i++) {
12572                if (i > 0) pw.print(", ");
12573                pw.print(mUserLru.get(i));
12574            }
12575            pw.println("]");
12576            if (dumpAll) {
12577                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12578            }
12579            synchronized (mUserProfileGroupIdsSelfLocked) {
12580                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12581                    pw.println("  mUserProfileGroupIds:");
12582                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12583                        pw.print("    User #");
12584                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12585                        pw.print(" -> profile #");
12586                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12587                    }
12588                }
12589            }
12590        }
12591        if (mHomeProcess != null && (dumpPackage == null
12592                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12593            if (needSep) {
12594                pw.println();
12595                needSep = false;
12596            }
12597            pw.println("  mHomeProcess: " + mHomeProcess);
12598        }
12599        if (mPreviousProcess != null && (dumpPackage == null
12600                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12601            if (needSep) {
12602                pw.println();
12603                needSep = false;
12604            }
12605            pw.println("  mPreviousProcess: " + mPreviousProcess);
12606        }
12607        if (dumpAll) {
12608            StringBuilder sb = new StringBuilder(128);
12609            sb.append("  mPreviousProcessVisibleTime: ");
12610            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12611            pw.println(sb);
12612        }
12613        if (mHeavyWeightProcess != null && (dumpPackage == null
12614                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12615            if (needSep) {
12616                pw.println();
12617                needSep = false;
12618            }
12619            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12620        }
12621        if (dumpPackage == null) {
12622            pw.println("  mConfiguration: " + mConfiguration);
12623        }
12624        if (dumpAll) {
12625            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12626            if (mCompatModePackages.getPackages().size() > 0) {
12627                boolean printed = false;
12628                for (Map.Entry<String, Integer> entry
12629                        : mCompatModePackages.getPackages().entrySet()) {
12630                    String pkg = entry.getKey();
12631                    int mode = entry.getValue();
12632                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12633                        continue;
12634                    }
12635                    if (!printed) {
12636                        pw.println("  mScreenCompatPackages:");
12637                        printed = true;
12638                    }
12639                    pw.print("    "); pw.print(pkg); pw.print(": ");
12640                            pw.print(mode); pw.println();
12641                }
12642            }
12643        }
12644        if (dumpPackage == null) {
12645            pw.println("  mWakefulness="
12646                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12647            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12648                    + lockScreenShownToString());
12649            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12650                    + " mTestPssMode=" + mTestPssMode);
12651        }
12652        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12653                || mOrigWaitForDebugger) {
12654            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12655                    || dumpPackage.equals(mOrigDebugApp)) {
12656                if (needSep) {
12657                    pw.println();
12658                    needSep = false;
12659                }
12660                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12661                        + " mDebugTransient=" + mDebugTransient
12662                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12663            }
12664        }
12665        if (mOpenGlTraceApp != null) {
12666            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12667                if (needSep) {
12668                    pw.println();
12669                    needSep = false;
12670                }
12671                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12672            }
12673        }
12674        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12675                || mProfileFd != null) {
12676            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12677                if (needSep) {
12678                    pw.println();
12679                    needSep = false;
12680                }
12681                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12682                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12683                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12684                        + mAutoStopProfiler);
12685                pw.println("  mProfileType=" + mProfileType);
12686            }
12687        }
12688        if (dumpPackage == null) {
12689            if (mAlwaysFinishActivities || mController != null) {
12690                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12691                        + " mController=" + mController);
12692            }
12693            if (dumpAll) {
12694                pw.println("  Total persistent processes: " + numPers);
12695                pw.println("  mProcessesReady=" + mProcessesReady
12696                        + " mSystemReady=" + mSystemReady
12697                        + " mBooted=" + mBooted
12698                        + " mFactoryTest=" + mFactoryTest);
12699                pw.println("  mBooting=" + mBooting
12700                        + " mCallFinishBooting=" + mCallFinishBooting
12701                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12702                pw.print("  mLastPowerCheckRealtime=");
12703                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12704                        pw.println("");
12705                pw.print("  mLastPowerCheckUptime=");
12706                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12707                        pw.println("");
12708                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12709                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12710                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12711                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12712                        + " (" + mLruProcesses.size() + " total)"
12713                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12714                        + " mNumServiceProcs=" + mNumServiceProcs
12715                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12716                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12717                        + " mLastMemoryLevel" + mLastMemoryLevel
12718                        + " mLastNumProcesses" + mLastNumProcesses);
12719                long now = SystemClock.uptimeMillis();
12720                pw.print("  mLastIdleTime=");
12721                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12722                        pw.print(" mLowRamSinceLastIdle=");
12723                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12724                        pw.println();
12725            }
12726        }
12727
12728        if (!printedAnything) {
12729            pw.println("  (nothing)");
12730        }
12731    }
12732
12733    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12734            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12735        if (mProcessesToGc.size() > 0) {
12736            boolean printed = false;
12737            long now = SystemClock.uptimeMillis();
12738            for (int i=0; i<mProcessesToGc.size(); i++) {
12739                ProcessRecord proc = mProcessesToGc.get(i);
12740                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12741                    continue;
12742                }
12743                if (!printed) {
12744                    if (needSep) pw.println();
12745                    needSep = true;
12746                    pw.println("  Processes that are waiting to GC:");
12747                    printed = true;
12748                }
12749                pw.print("    Process "); pw.println(proc);
12750                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12751                        pw.print(", last gced=");
12752                        pw.print(now-proc.lastRequestedGc);
12753                        pw.print(" ms ago, last lowMem=");
12754                        pw.print(now-proc.lastLowMemory);
12755                        pw.println(" ms ago");
12756
12757            }
12758        }
12759        return needSep;
12760    }
12761
12762    void printOomLevel(PrintWriter pw, String name, int adj) {
12763        pw.print("    ");
12764        if (adj >= 0) {
12765            pw.print(' ');
12766            if (adj < 10) pw.print(' ');
12767        } else {
12768            if (adj > -10) pw.print(' ');
12769        }
12770        pw.print(adj);
12771        pw.print(": ");
12772        pw.print(name);
12773        pw.print(" (");
12774        pw.print(mProcessList.getMemLevel(adj)/1024);
12775        pw.println(" kB)");
12776    }
12777
12778    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12779            int opti, boolean dumpAll) {
12780        boolean needSep = false;
12781
12782        if (mLruProcesses.size() > 0) {
12783            if (needSep) pw.println();
12784            needSep = true;
12785            pw.println("  OOM levels:");
12786            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12787            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12788            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12789            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12790            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12791            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12792            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12793            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12794            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12795            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12796            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12797            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12798            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12799            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12800
12801            if (needSep) pw.println();
12802            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12803                    pw.print(" total, non-act at ");
12804                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12805                    pw.print(", non-svc at ");
12806                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12807                    pw.println("):");
12808            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12809            needSep = true;
12810        }
12811
12812        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12813
12814        pw.println();
12815        pw.println("  mHomeProcess: " + mHomeProcess);
12816        pw.println("  mPreviousProcess: " + mPreviousProcess);
12817        if (mHeavyWeightProcess != null) {
12818            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12819        }
12820
12821        return true;
12822    }
12823
12824    /**
12825     * There are three ways to call this:
12826     *  - no provider specified: dump all the providers
12827     *  - a flattened component name that matched an existing provider was specified as the
12828     *    first arg: dump that one provider
12829     *  - the first arg isn't the flattened component name of an existing provider:
12830     *    dump all providers whose component contains the first arg as a substring
12831     */
12832    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12833            int opti, boolean dumpAll) {
12834        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12835    }
12836
12837    static class ItemMatcher {
12838        ArrayList<ComponentName> components;
12839        ArrayList<String> strings;
12840        ArrayList<Integer> objects;
12841        boolean all;
12842
12843        ItemMatcher() {
12844            all = true;
12845        }
12846
12847        void build(String name) {
12848            ComponentName componentName = ComponentName.unflattenFromString(name);
12849            if (componentName != null) {
12850                if (components == null) {
12851                    components = new ArrayList<ComponentName>();
12852                }
12853                components.add(componentName);
12854                all = false;
12855            } else {
12856                int objectId = 0;
12857                // Not a '/' separated full component name; maybe an object ID?
12858                try {
12859                    objectId = Integer.parseInt(name, 16);
12860                    if (objects == null) {
12861                        objects = new ArrayList<Integer>();
12862                    }
12863                    objects.add(objectId);
12864                    all = false;
12865                } catch (RuntimeException e) {
12866                    // Not an integer; just do string match.
12867                    if (strings == null) {
12868                        strings = new ArrayList<String>();
12869                    }
12870                    strings.add(name);
12871                    all = false;
12872                }
12873            }
12874        }
12875
12876        int build(String[] args, int opti) {
12877            for (; opti<args.length; opti++) {
12878                String name = args[opti];
12879                if ("--".equals(name)) {
12880                    return opti+1;
12881                }
12882                build(name);
12883            }
12884            return opti;
12885        }
12886
12887        boolean match(Object object, ComponentName comp) {
12888            if (all) {
12889                return true;
12890            }
12891            if (components != null) {
12892                for (int i=0; i<components.size(); i++) {
12893                    if (components.get(i).equals(comp)) {
12894                        return true;
12895                    }
12896                }
12897            }
12898            if (objects != null) {
12899                for (int i=0; i<objects.size(); i++) {
12900                    if (System.identityHashCode(object) == objects.get(i)) {
12901                        return true;
12902                    }
12903                }
12904            }
12905            if (strings != null) {
12906                String flat = comp.flattenToString();
12907                for (int i=0; i<strings.size(); i++) {
12908                    if (flat.contains(strings.get(i))) {
12909                        return true;
12910                    }
12911                }
12912            }
12913            return false;
12914        }
12915    }
12916
12917    /**
12918     * There are three things that cmd can be:
12919     *  - a flattened component name that matches an existing activity
12920     *  - the cmd arg isn't the flattened component name of an existing activity:
12921     *    dump all activity whose component contains the cmd as a substring
12922     *  - A hex number of the ActivityRecord object instance.
12923     */
12924    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12925            int opti, boolean dumpAll) {
12926        ArrayList<ActivityRecord> activities;
12927
12928        synchronized (this) {
12929            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12930        }
12931
12932        if (activities.size() <= 0) {
12933            return false;
12934        }
12935
12936        String[] newArgs = new String[args.length - opti];
12937        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12938
12939        TaskRecord lastTask = null;
12940        boolean needSep = false;
12941        for (int i=activities.size()-1; i>=0; i--) {
12942            ActivityRecord r = activities.get(i);
12943            if (needSep) {
12944                pw.println();
12945            }
12946            needSep = true;
12947            synchronized (this) {
12948                if (lastTask != r.task) {
12949                    lastTask = r.task;
12950                    pw.print("TASK "); pw.print(lastTask.affinity);
12951                            pw.print(" id="); pw.println(lastTask.taskId);
12952                    if (dumpAll) {
12953                        lastTask.dump(pw, "  ");
12954                    }
12955                }
12956            }
12957            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12958        }
12959        return true;
12960    }
12961
12962    /**
12963     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12964     * there is a thread associated with the activity.
12965     */
12966    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12967            final ActivityRecord r, String[] args, boolean dumpAll) {
12968        String innerPrefix = prefix + "  ";
12969        synchronized (this) {
12970            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12971                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12972                    pw.print(" pid=");
12973                    if (r.app != null) pw.println(r.app.pid);
12974                    else pw.println("(not running)");
12975            if (dumpAll) {
12976                r.dump(pw, innerPrefix);
12977            }
12978        }
12979        if (r.app != null && r.app.thread != null) {
12980            // flush anything that is already in the PrintWriter since the thread is going
12981            // to write to the file descriptor directly
12982            pw.flush();
12983            try {
12984                TransferPipe tp = new TransferPipe();
12985                try {
12986                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12987                            r.appToken, innerPrefix, args);
12988                    tp.go(fd);
12989                } finally {
12990                    tp.kill();
12991                }
12992            } catch (IOException e) {
12993                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12994            } catch (RemoteException e) {
12995                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12996            }
12997        }
12998    }
12999
13000    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13001            int opti, boolean dumpAll, String dumpPackage) {
13002        boolean needSep = false;
13003        boolean onlyHistory = false;
13004        boolean printedAnything = false;
13005
13006        if ("history".equals(dumpPackage)) {
13007            if (opti < args.length && "-s".equals(args[opti])) {
13008                dumpAll = false;
13009            }
13010            onlyHistory = true;
13011            dumpPackage = null;
13012        }
13013
13014        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13015        if (!onlyHistory && dumpAll) {
13016            if (mRegisteredReceivers.size() > 0) {
13017                boolean printed = false;
13018                Iterator it = mRegisteredReceivers.values().iterator();
13019                while (it.hasNext()) {
13020                    ReceiverList r = (ReceiverList)it.next();
13021                    if (dumpPackage != null && (r.app == null ||
13022                            !dumpPackage.equals(r.app.info.packageName))) {
13023                        continue;
13024                    }
13025                    if (!printed) {
13026                        pw.println("  Registered Receivers:");
13027                        needSep = true;
13028                        printed = true;
13029                        printedAnything = true;
13030                    }
13031                    pw.print("  * "); pw.println(r);
13032                    r.dump(pw, "    ");
13033                }
13034            }
13035
13036            if (mReceiverResolver.dump(pw, needSep ?
13037                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13038                    "    ", dumpPackage, false, false)) {
13039                needSep = true;
13040                printedAnything = true;
13041            }
13042        }
13043
13044        for (BroadcastQueue q : mBroadcastQueues) {
13045            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13046            printedAnything |= needSep;
13047        }
13048
13049        needSep = true;
13050
13051        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13052            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13053                if (needSep) {
13054                    pw.println();
13055                }
13056                needSep = true;
13057                printedAnything = true;
13058                pw.print("  Sticky broadcasts for user ");
13059                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13060                StringBuilder sb = new StringBuilder(128);
13061                for (Map.Entry<String, ArrayList<Intent>> ent
13062                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13063                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13064                    if (dumpAll) {
13065                        pw.println(":");
13066                        ArrayList<Intent> intents = ent.getValue();
13067                        final int N = intents.size();
13068                        for (int i=0; i<N; i++) {
13069                            sb.setLength(0);
13070                            sb.append("    Intent: ");
13071                            intents.get(i).toShortString(sb, false, true, false, false);
13072                            pw.println(sb.toString());
13073                            Bundle bundle = intents.get(i).getExtras();
13074                            if (bundle != null) {
13075                                pw.print("      ");
13076                                pw.println(bundle.toString());
13077                            }
13078                        }
13079                    } else {
13080                        pw.println("");
13081                    }
13082                }
13083            }
13084        }
13085
13086        if (!onlyHistory && dumpAll) {
13087            pw.println();
13088            for (BroadcastQueue queue : mBroadcastQueues) {
13089                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13090                        + queue.mBroadcastsScheduled);
13091            }
13092            pw.println("  mHandler:");
13093            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13094            needSep = true;
13095            printedAnything = true;
13096        }
13097
13098        if (!printedAnything) {
13099            pw.println("  (nothing)");
13100        }
13101    }
13102
13103    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13104            int opti, boolean dumpAll, String dumpPackage) {
13105        boolean needSep;
13106        boolean printedAnything = false;
13107
13108        ItemMatcher matcher = new ItemMatcher();
13109        matcher.build(args, opti);
13110
13111        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13112
13113        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13114        printedAnything |= needSep;
13115
13116        if (mLaunchingProviders.size() > 0) {
13117            boolean printed = false;
13118            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13119                ContentProviderRecord r = mLaunchingProviders.get(i);
13120                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13121                    continue;
13122                }
13123                if (!printed) {
13124                    if (needSep) pw.println();
13125                    needSep = true;
13126                    pw.println("  Launching content providers:");
13127                    printed = true;
13128                    printedAnything = true;
13129                }
13130                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13131                        pw.println(r);
13132            }
13133        }
13134
13135        if (mGrantedUriPermissions.size() > 0) {
13136            boolean printed = false;
13137            int dumpUid = -2;
13138            if (dumpPackage != null) {
13139                try {
13140                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13141                } catch (NameNotFoundException e) {
13142                    dumpUid = -1;
13143                }
13144            }
13145            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13146                int uid = mGrantedUriPermissions.keyAt(i);
13147                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13148                    continue;
13149                }
13150                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13151                if (!printed) {
13152                    if (needSep) pw.println();
13153                    needSep = true;
13154                    pw.println("  Granted Uri Permissions:");
13155                    printed = true;
13156                    printedAnything = true;
13157                }
13158                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13159                for (UriPermission perm : perms.values()) {
13160                    pw.print("    "); pw.println(perm);
13161                    if (dumpAll) {
13162                        perm.dump(pw, "      ");
13163                    }
13164                }
13165            }
13166        }
13167
13168        if (!printedAnything) {
13169            pw.println("  (nothing)");
13170        }
13171    }
13172
13173    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13174            int opti, boolean dumpAll, String dumpPackage) {
13175        boolean printed = false;
13176
13177        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13178
13179        if (mIntentSenderRecords.size() > 0) {
13180            Iterator<WeakReference<PendingIntentRecord>> it
13181                    = mIntentSenderRecords.values().iterator();
13182            while (it.hasNext()) {
13183                WeakReference<PendingIntentRecord> ref = it.next();
13184                PendingIntentRecord rec = ref != null ? ref.get(): null;
13185                if (dumpPackage != null && (rec == null
13186                        || !dumpPackage.equals(rec.key.packageName))) {
13187                    continue;
13188                }
13189                printed = true;
13190                if (rec != null) {
13191                    pw.print("  * "); pw.println(rec);
13192                    if (dumpAll) {
13193                        rec.dump(pw, "    ");
13194                    }
13195                } else {
13196                    pw.print("  * "); pw.println(ref);
13197                }
13198            }
13199        }
13200
13201        if (!printed) {
13202            pw.println("  (nothing)");
13203        }
13204    }
13205
13206    private static final int dumpProcessList(PrintWriter pw,
13207            ActivityManagerService service, List list,
13208            String prefix, String normalLabel, String persistentLabel,
13209            String dumpPackage) {
13210        int numPers = 0;
13211        final int N = list.size()-1;
13212        for (int i=N; i>=0; i--) {
13213            ProcessRecord r = (ProcessRecord)list.get(i);
13214            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13215                continue;
13216            }
13217            pw.println(String.format("%s%s #%2d: %s",
13218                    prefix, (r.persistent ? persistentLabel : normalLabel),
13219                    i, r.toString()));
13220            if (r.persistent) {
13221                numPers++;
13222            }
13223        }
13224        return numPers;
13225    }
13226
13227    private static final boolean dumpProcessOomList(PrintWriter pw,
13228            ActivityManagerService service, List<ProcessRecord> origList,
13229            String prefix, String normalLabel, String persistentLabel,
13230            boolean inclDetails, String dumpPackage) {
13231
13232        ArrayList<Pair<ProcessRecord, Integer>> list
13233                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13234        for (int i=0; i<origList.size(); i++) {
13235            ProcessRecord r = origList.get(i);
13236            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13237                continue;
13238            }
13239            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13240        }
13241
13242        if (list.size() <= 0) {
13243            return false;
13244        }
13245
13246        Comparator<Pair<ProcessRecord, Integer>> comparator
13247                = new Comparator<Pair<ProcessRecord, Integer>>() {
13248            @Override
13249            public int compare(Pair<ProcessRecord, Integer> object1,
13250                    Pair<ProcessRecord, Integer> object2) {
13251                if (object1.first.setAdj != object2.first.setAdj) {
13252                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13253                }
13254                if (object1.second.intValue() != object2.second.intValue()) {
13255                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13256                }
13257                return 0;
13258            }
13259        };
13260
13261        Collections.sort(list, comparator);
13262
13263        final long curRealtime = SystemClock.elapsedRealtime();
13264        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13265        final long curUptime = SystemClock.uptimeMillis();
13266        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13267
13268        for (int i=list.size()-1; i>=0; i--) {
13269            ProcessRecord r = list.get(i).first;
13270            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13271            char schedGroup;
13272            switch (r.setSchedGroup) {
13273                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13274                    schedGroup = 'B';
13275                    break;
13276                case Process.THREAD_GROUP_DEFAULT:
13277                    schedGroup = 'F';
13278                    break;
13279                default:
13280                    schedGroup = '?';
13281                    break;
13282            }
13283            char foreground;
13284            if (r.foregroundActivities) {
13285                foreground = 'A';
13286            } else if (r.foregroundServices) {
13287                foreground = 'S';
13288            } else {
13289                foreground = ' ';
13290            }
13291            String procState = ProcessList.makeProcStateString(r.curProcState);
13292            pw.print(prefix);
13293            pw.print(r.persistent ? persistentLabel : normalLabel);
13294            pw.print(" #");
13295            int num = (origList.size()-1)-list.get(i).second;
13296            if (num < 10) pw.print(' ');
13297            pw.print(num);
13298            pw.print(": ");
13299            pw.print(oomAdj);
13300            pw.print(' ');
13301            pw.print(schedGroup);
13302            pw.print('/');
13303            pw.print(foreground);
13304            pw.print('/');
13305            pw.print(procState);
13306            pw.print(" trm:");
13307            if (r.trimMemoryLevel < 10) pw.print(' ');
13308            pw.print(r.trimMemoryLevel);
13309            pw.print(' ');
13310            pw.print(r.toShortString());
13311            pw.print(" (");
13312            pw.print(r.adjType);
13313            pw.println(')');
13314            if (r.adjSource != null || r.adjTarget != null) {
13315                pw.print(prefix);
13316                pw.print("    ");
13317                if (r.adjTarget instanceof ComponentName) {
13318                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13319                } else if (r.adjTarget != null) {
13320                    pw.print(r.adjTarget.toString());
13321                } else {
13322                    pw.print("{null}");
13323                }
13324                pw.print("<=");
13325                if (r.adjSource instanceof ProcessRecord) {
13326                    pw.print("Proc{");
13327                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13328                    pw.println("}");
13329                } else if (r.adjSource != null) {
13330                    pw.println(r.adjSource.toString());
13331                } else {
13332                    pw.println("{null}");
13333                }
13334            }
13335            if (inclDetails) {
13336                pw.print(prefix);
13337                pw.print("    ");
13338                pw.print("oom: max="); pw.print(r.maxAdj);
13339                pw.print(" curRaw="); pw.print(r.curRawAdj);
13340                pw.print(" setRaw="); pw.print(r.setRawAdj);
13341                pw.print(" cur="); pw.print(r.curAdj);
13342                pw.print(" set="); pw.println(r.setAdj);
13343                pw.print(prefix);
13344                pw.print("    ");
13345                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13346                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13347                pw.print(" lastPss="); pw.print(r.lastPss);
13348                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13349                pw.print(prefix);
13350                pw.print("    ");
13351                pw.print("cached="); pw.print(r.cached);
13352                pw.print(" empty="); pw.print(r.empty);
13353                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13354
13355                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13356                    if (r.lastWakeTime != 0) {
13357                        long wtime;
13358                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13359                        synchronized (stats) {
13360                            wtime = stats.getProcessWakeTime(r.info.uid,
13361                                    r.pid, curRealtime);
13362                        }
13363                        long timeUsed = wtime - r.lastWakeTime;
13364                        pw.print(prefix);
13365                        pw.print("    ");
13366                        pw.print("keep awake over ");
13367                        TimeUtils.formatDuration(realtimeSince, pw);
13368                        pw.print(" used ");
13369                        TimeUtils.formatDuration(timeUsed, pw);
13370                        pw.print(" (");
13371                        pw.print((timeUsed*100)/realtimeSince);
13372                        pw.println("%)");
13373                    }
13374                    if (r.lastCpuTime != 0) {
13375                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13376                        pw.print(prefix);
13377                        pw.print("    ");
13378                        pw.print("run cpu over ");
13379                        TimeUtils.formatDuration(uptimeSince, pw);
13380                        pw.print(" used ");
13381                        TimeUtils.formatDuration(timeUsed, pw);
13382                        pw.print(" (");
13383                        pw.print((timeUsed*100)/uptimeSince);
13384                        pw.println("%)");
13385                    }
13386                }
13387            }
13388        }
13389        return true;
13390    }
13391
13392    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13393            String[] args) {
13394        ArrayList<ProcessRecord> procs;
13395        synchronized (this) {
13396            if (args != null && args.length > start
13397                    && args[start].charAt(0) != '-') {
13398                procs = new ArrayList<ProcessRecord>();
13399                int pid = -1;
13400                try {
13401                    pid = Integer.parseInt(args[start]);
13402                } catch (NumberFormatException e) {
13403                }
13404                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13405                    ProcessRecord proc = mLruProcesses.get(i);
13406                    if (proc.pid == pid) {
13407                        procs.add(proc);
13408                    } else if (allPkgs && proc.pkgList != null
13409                            && proc.pkgList.containsKey(args[start])) {
13410                        procs.add(proc);
13411                    } else if (proc.processName.equals(args[start])) {
13412                        procs.add(proc);
13413                    }
13414                }
13415                if (procs.size() <= 0) {
13416                    return null;
13417                }
13418            } else {
13419                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13420            }
13421        }
13422        return procs;
13423    }
13424
13425    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13426            PrintWriter pw, String[] args) {
13427        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13428        if (procs == null) {
13429            pw.println("No process found for: " + args[0]);
13430            return;
13431        }
13432
13433        long uptime = SystemClock.uptimeMillis();
13434        long realtime = SystemClock.elapsedRealtime();
13435        pw.println("Applications Graphics Acceleration Info:");
13436        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13437
13438        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13439            ProcessRecord r = procs.get(i);
13440            if (r.thread != null) {
13441                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13442                pw.flush();
13443                try {
13444                    TransferPipe tp = new TransferPipe();
13445                    try {
13446                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13447                        tp.go(fd);
13448                    } finally {
13449                        tp.kill();
13450                    }
13451                } catch (IOException e) {
13452                    pw.println("Failure while dumping the app: " + r);
13453                    pw.flush();
13454                } catch (RemoteException e) {
13455                    pw.println("Got a RemoteException while dumping the app " + r);
13456                    pw.flush();
13457                }
13458            }
13459        }
13460    }
13461
13462    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13463        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13464        if (procs == null) {
13465            pw.println("No process found for: " + args[0]);
13466            return;
13467        }
13468
13469        pw.println("Applications Database Info:");
13470
13471        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13472            ProcessRecord r = procs.get(i);
13473            if (r.thread != null) {
13474                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13475                pw.flush();
13476                try {
13477                    TransferPipe tp = new TransferPipe();
13478                    try {
13479                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13480                        tp.go(fd);
13481                    } finally {
13482                        tp.kill();
13483                    }
13484                } catch (IOException e) {
13485                    pw.println("Failure while dumping the app: " + r);
13486                    pw.flush();
13487                } catch (RemoteException e) {
13488                    pw.println("Got a RemoteException while dumping the app " + r);
13489                    pw.flush();
13490                }
13491            }
13492        }
13493    }
13494
13495    final static class MemItem {
13496        final boolean isProc;
13497        final String label;
13498        final String shortLabel;
13499        final long pss;
13500        final int id;
13501        final boolean hasActivities;
13502        ArrayList<MemItem> subitems;
13503
13504        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13505                boolean _hasActivities) {
13506            isProc = true;
13507            label = _label;
13508            shortLabel = _shortLabel;
13509            pss = _pss;
13510            id = _id;
13511            hasActivities = _hasActivities;
13512        }
13513
13514        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13515            isProc = false;
13516            label = _label;
13517            shortLabel = _shortLabel;
13518            pss = _pss;
13519            id = _id;
13520            hasActivities = false;
13521        }
13522    }
13523
13524    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13525            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13526        if (sort && !isCompact) {
13527            Collections.sort(items, new Comparator<MemItem>() {
13528                @Override
13529                public int compare(MemItem lhs, MemItem rhs) {
13530                    if (lhs.pss < rhs.pss) {
13531                        return 1;
13532                    } else if (lhs.pss > rhs.pss) {
13533                        return -1;
13534                    }
13535                    return 0;
13536                }
13537            });
13538        }
13539
13540        for (int i=0; i<items.size(); i++) {
13541            MemItem mi = items.get(i);
13542            if (!isCompact) {
13543                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13544            } else if (mi.isProc) {
13545                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13546                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13547                pw.println(mi.hasActivities ? ",a" : ",e");
13548            } else {
13549                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13550                pw.println(mi.pss);
13551            }
13552            if (mi.subitems != null) {
13553                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13554                        true, isCompact);
13555            }
13556        }
13557    }
13558
13559    // These are in KB.
13560    static final long[] DUMP_MEM_BUCKETS = new long[] {
13561        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13562        120*1024, 160*1024, 200*1024,
13563        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13564        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13565    };
13566
13567    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13568            boolean stackLike) {
13569        int start = label.lastIndexOf('.');
13570        if (start >= 0) start++;
13571        else start = 0;
13572        int end = label.length();
13573        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13574            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13575                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13576                out.append(bucket);
13577                out.append(stackLike ? "MB." : "MB ");
13578                out.append(label, start, end);
13579                return;
13580            }
13581        }
13582        out.append(memKB/1024);
13583        out.append(stackLike ? "MB." : "MB ");
13584        out.append(label, start, end);
13585    }
13586
13587    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13588            ProcessList.NATIVE_ADJ,
13589            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13590            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13591            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13592            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13593            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13594            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13595    };
13596    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13597            "Native",
13598            "System", "Persistent", "Persistent Service", "Foreground",
13599            "Visible", "Perceptible",
13600            "Heavy Weight", "Backup",
13601            "A Services", "Home",
13602            "Previous", "B Services", "Cached"
13603    };
13604    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13605            "native",
13606            "sys", "pers", "persvc", "fore",
13607            "vis", "percept",
13608            "heavy", "backup",
13609            "servicea", "home",
13610            "prev", "serviceb", "cached"
13611    };
13612
13613    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13614            long realtime, boolean isCheckinRequest, boolean isCompact) {
13615        if (isCheckinRequest || isCompact) {
13616            // short checkin version
13617            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13618        } else {
13619            pw.println("Applications Memory Usage (kB):");
13620            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13621        }
13622    }
13623
13624    private static final int KSM_SHARED = 0;
13625    private static final int KSM_SHARING = 1;
13626    private static final int KSM_UNSHARED = 2;
13627    private static final int KSM_VOLATILE = 3;
13628
13629    private final long[] getKsmInfo() {
13630        long[] longOut = new long[4];
13631        final int[] SINGLE_LONG_FORMAT = new int[] {
13632            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13633        };
13634        long[] longTmp = new long[1];
13635        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13636                SINGLE_LONG_FORMAT, null, longTmp, null);
13637        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13638        longTmp[0] = 0;
13639        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13640                SINGLE_LONG_FORMAT, null, longTmp, null);
13641        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13642        longTmp[0] = 0;
13643        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13644                SINGLE_LONG_FORMAT, null, longTmp, null);
13645        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13646        longTmp[0] = 0;
13647        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13648                SINGLE_LONG_FORMAT, null, longTmp, null);
13649        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13650        return longOut;
13651    }
13652
13653    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13654            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13655        boolean dumpDetails = false;
13656        boolean dumpFullDetails = false;
13657        boolean dumpDalvik = false;
13658        boolean oomOnly = false;
13659        boolean isCompact = false;
13660        boolean localOnly = false;
13661        boolean packages = false;
13662
13663        int opti = 0;
13664        while (opti < args.length) {
13665            String opt = args[opti];
13666            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13667                break;
13668            }
13669            opti++;
13670            if ("-a".equals(opt)) {
13671                dumpDetails = true;
13672                dumpFullDetails = true;
13673                dumpDalvik = true;
13674            } else if ("-d".equals(opt)) {
13675                dumpDalvik = true;
13676            } else if ("-c".equals(opt)) {
13677                isCompact = true;
13678            } else if ("--oom".equals(opt)) {
13679                oomOnly = true;
13680            } else if ("--local".equals(opt)) {
13681                localOnly = true;
13682            } else if ("--package".equals(opt)) {
13683                packages = true;
13684            } else if ("-h".equals(opt)) {
13685                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13686                pw.println("  -a: include all available information for each process.");
13687                pw.println("  -d: include dalvik details when dumping process details.");
13688                pw.println("  -c: dump in a compact machine-parseable representation.");
13689                pw.println("  --oom: only show processes organized by oom adj.");
13690                pw.println("  --local: only collect details locally, don't call process.");
13691                pw.println("  --package: interpret process arg as package, dumping all");
13692                pw.println("             processes that have loaded that package.");
13693                pw.println("If [process] is specified it can be the name or ");
13694                pw.println("pid of a specific process to dump.");
13695                return;
13696            } else {
13697                pw.println("Unknown argument: " + opt + "; use -h for help");
13698            }
13699        }
13700
13701        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13702        long uptime = SystemClock.uptimeMillis();
13703        long realtime = SystemClock.elapsedRealtime();
13704        final long[] tmpLong = new long[1];
13705
13706        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13707        if (procs == null) {
13708            // No Java processes.  Maybe they want to print a native process.
13709            if (args != null && args.length > opti
13710                    && args[opti].charAt(0) != '-') {
13711                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13712                        = new ArrayList<ProcessCpuTracker.Stats>();
13713                updateCpuStatsNow();
13714                int findPid = -1;
13715                try {
13716                    findPid = Integer.parseInt(args[opti]);
13717                } catch (NumberFormatException e) {
13718                }
13719                synchronized (mProcessCpuTracker) {
13720                    final int N = mProcessCpuTracker.countStats();
13721                    for (int i=0; i<N; i++) {
13722                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13723                        if (st.pid == findPid || (st.baseName != null
13724                                && st.baseName.equals(args[opti]))) {
13725                            nativeProcs.add(st);
13726                        }
13727                    }
13728                }
13729                if (nativeProcs.size() > 0) {
13730                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13731                            isCompact);
13732                    Debug.MemoryInfo mi = null;
13733                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13734                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13735                        final int pid = r.pid;
13736                        if (!isCheckinRequest && dumpDetails) {
13737                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13738                        }
13739                        if (mi == null) {
13740                            mi = new Debug.MemoryInfo();
13741                        }
13742                        if (dumpDetails || (!brief && !oomOnly)) {
13743                            Debug.getMemoryInfo(pid, mi);
13744                        } else {
13745                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13746                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13747                        }
13748                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13749                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13750                        if (isCheckinRequest) {
13751                            pw.println();
13752                        }
13753                    }
13754                    return;
13755                }
13756            }
13757            pw.println("No process found for: " + args[opti]);
13758            return;
13759        }
13760
13761        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13762            dumpDetails = true;
13763        }
13764
13765        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13766
13767        String[] innerArgs = new String[args.length-opti];
13768        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13769
13770        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13771        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13772        long nativePss = 0;
13773        long dalvikPss = 0;
13774        long otherPss = 0;
13775        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13776
13777        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13778        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13779                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13780
13781        long totalPss = 0;
13782        long cachedPss = 0;
13783
13784        Debug.MemoryInfo mi = null;
13785        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13786            final ProcessRecord r = procs.get(i);
13787            final IApplicationThread thread;
13788            final int pid;
13789            final int oomAdj;
13790            final boolean hasActivities;
13791            synchronized (this) {
13792                thread = r.thread;
13793                pid = r.pid;
13794                oomAdj = r.getSetAdjWithServices();
13795                hasActivities = r.activities.size() > 0;
13796            }
13797            if (thread != null) {
13798                if (!isCheckinRequest && dumpDetails) {
13799                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13800                }
13801                if (mi == null) {
13802                    mi = new Debug.MemoryInfo();
13803                }
13804                if (dumpDetails || (!brief && !oomOnly)) {
13805                    Debug.getMemoryInfo(pid, mi);
13806                } else {
13807                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13808                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13809                }
13810                if (dumpDetails) {
13811                    if (localOnly) {
13812                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13813                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13814                        if (isCheckinRequest) {
13815                            pw.println();
13816                        }
13817                    } else {
13818                        try {
13819                            pw.flush();
13820                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13821                                    dumpDalvik, innerArgs);
13822                        } catch (RemoteException e) {
13823                            if (!isCheckinRequest) {
13824                                pw.println("Got RemoteException!");
13825                                pw.flush();
13826                            }
13827                        }
13828                    }
13829                }
13830
13831                final long myTotalPss = mi.getTotalPss();
13832                final long myTotalUss = mi.getTotalUss();
13833
13834                synchronized (this) {
13835                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13836                        // Record this for posterity if the process has been stable.
13837                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13838                    }
13839                }
13840
13841                if (!isCheckinRequest && mi != null) {
13842                    totalPss += myTotalPss;
13843                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13844                            (hasActivities ? " / activities)" : ")"),
13845                            r.processName, myTotalPss, pid, hasActivities);
13846                    procMems.add(pssItem);
13847                    procMemsMap.put(pid, pssItem);
13848
13849                    nativePss += mi.nativePss;
13850                    dalvikPss += mi.dalvikPss;
13851                    otherPss += mi.otherPss;
13852                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13853                        long mem = mi.getOtherPss(j);
13854                        miscPss[j] += mem;
13855                        otherPss -= mem;
13856                    }
13857
13858                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13859                        cachedPss += myTotalPss;
13860                    }
13861
13862                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13863                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13864                                || oomIndex == (oomPss.length-1)) {
13865                            oomPss[oomIndex] += myTotalPss;
13866                            if (oomProcs[oomIndex] == null) {
13867                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13868                            }
13869                            oomProcs[oomIndex].add(pssItem);
13870                            break;
13871                        }
13872                    }
13873                }
13874            }
13875        }
13876
13877        long nativeProcTotalPss = 0;
13878
13879        if (!isCheckinRequest && procs.size() > 1 && !packages) {
13880            // If we are showing aggregations, also look for native processes to
13881            // include so that our aggregations are more accurate.
13882            updateCpuStatsNow();
13883            mi = null;
13884            synchronized (mProcessCpuTracker) {
13885                final int N = mProcessCpuTracker.countStats();
13886                for (int i=0; i<N; i++) {
13887                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13888                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13889                        if (mi == null) {
13890                            mi = new Debug.MemoryInfo();
13891                        }
13892                        if (!brief && !oomOnly) {
13893                            Debug.getMemoryInfo(st.pid, mi);
13894                        } else {
13895                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
13896                            mi.nativePrivateDirty = (int)tmpLong[0];
13897                        }
13898
13899                        final long myTotalPss = mi.getTotalPss();
13900                        totalPss += myTotalPss;
13901                        nativeProcTotalPss += myTotalPss;
13902
13903                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13904                                st.name, myTotalPss, st.pid, false);
13905                        procMems.add(pssItem);
13906
13907                        nativePss += mi.nativePss;
13908                        dalvikPss += mi.dalvikPss;
13909                        otherPss += mi.otherPss;
13910                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13911                            long mem = mi.getOtherPss(j);
13912                            miscPss[j] += mem;
13913                            otherPss -= mem;
13914                        }
13915                        oomPss[0] += myTotalPss;
13916                        if (oomProcs[0] == null) {
13917                            oomProcs[0] = new ArrayList<MemItem>();
13918                        }
13919                        oomProcs[0].add(pssItem);
13920                    }
13921                }
13922            }
13923
13924            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13925
13926            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13927            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13928            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13929            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13930                String label = Debug.MemoryInfo.getOtherLabel(j);
13931                catMems.add(new MemItem(label, label, miscPss[j], j));
13932            }
13933
13934            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13935            for (int j=0; j<oomPss.length; j++) {
13936                if (oomPss[j] != 0) {
13937                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13938                            : DUMP_MEM_OOM_LABEL[j];
13939                    MemItem item = new MemItem(label, label, oomPss[j],
13940                            DUMP_MEM_OOM_ADJ[j]);
13941                    item.subitems = oomProcs[j];
13942                    oomMems.add(item);
13943                }
13944            }
13945
13946            if (!brief && !oomOnly && !isCompact) {
13947                pw.println();
13948                pw.println("Total PSS by process:");
13949                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13950                pw.println();
13951            }
13952            if (!isCompact) {
13953                pw.println("Total PSS by OOM adjustment:");
13954            }
13955            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13956            if (!brief && !oomOnly) {
13957                PrintWriter out = categoryPw != null ? categoryPw : pw;
13958                if (!isCompact) {
13959                    out.println();
13960                    out.println("Total PSS by category:");
13961                }
13962                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13963            }
13964            if (!isCompact) {
13965                pw.println();
13966            }
13967            MemInfoReader memInfo = new MemInfoReader();
13968            memInfo.readMemInfo();
13969            if (nativeProcTotalPss > 0) {
13970                synchronized (this) {
13971                    final long cachedKb = memInfo.getCachedSizeKb();
13972                    final long freeKb = memInfo.getFreeSizeKb();
13973                    final long zramKb = memInfo.getZramTotalSizeKb();
13974                    final long kernelKb = memInfo.getKernelUsedSizeKb();
13975                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
13976                            kernelKb*1024, nativeProcTotalPss*1024);
13977                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
13978                            nativeProcTotalPss);
13979                }
13980            }
13981            if (!brief) {
13982                if (!isCompact) {
13983                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13984                    pw.print(" kB (status ");
13985                    switch (mLastMemoryLevel) {
13986                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13987                            pw.println("normal)");
13988                            break;
13989                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13990                            pw.println("moderate)");
13991                            break;
13992                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13993                            pw.println("low)");
13994                            break;
13995                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13996                            pw.println("critical)");
13997                            break;
13998                        default:
13999                            pw.print(mLastMemoryLevel);
14000                            pw.println(")");
14001                            break;
14002                    }
14003                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14004                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14005                            pw.print(cachedPss); pw.print(" cached pss + ");
14006                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14007                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14008                } else {
14009                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14010                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14011                            + memInfo.getFreeSizeKb()); pw.print(",");
14012                    pw.println(totalPss - cachedPss);
14013                }
14014            }
14015            if (!isCompact) {
14016                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14017                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14018                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14019                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14020                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14021                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14022                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14023            }
14024            if (!brief) {
14025                if (memInfo.getZramTotalSizeKb() != 0) {
14026                    if (!isCompact) {
14027                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14028                                pw.print(" kB physical used for ");
14029                                pw.print(memInfo.getSwapTotalSizeKb()
14030                                        - memInfo.getSwapFreeSizeKb());
14031                                pw.print(" kB in swap (");
14032                                pw.print(memInfo.getSwapTotalSizeKb());
14033                                pw.println(" kB total swap)");
14034                    } else {
14035                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14036                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14037                                pw.println(memInfo.getSwapFreeSizeKb());
14038                    }
14039                }
14040                final long[] ksm = getKsmInfo();
14041                if (!isCompact) {
14042                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14043                            || ksm[KSM_VOLATILE] != 0) {
14044                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14045                                pw.print(" kB saved from shared ");
14046                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14047                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14048                                pw.print(" kB unshared; ");
14049                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14050                    }
14051                    pw.print("   Tuning: ");
14052                    pw.print(ActivityManager.staticGetMemoryClass());
14053                    pw.print(" (large ");
14054                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14055                    pw.print("), oom ");
14056                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14057                    pw.print(" kB");
14058                    pw.print(", restore limit ");
14059                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14060                    pw.print(" kB");
14061                    if (ActivityManager.isLowRamDeviceStatic()) {
14062                        pw.print(" (low-ram)");
14063                    }
14064                    if (ActivityManager.isHighEndGfx()) {
14065                        pw.print(" (high-end-gfx)");
14066                    }
14067                    pw.println();
14068                } else {
14069                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14070                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14071                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14072                    pw.print("tuning,");
14073                    pw.print(ActivityManager.staticGetMemoryClass());
14074                    pw.print(',');
14075                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14076                    pw.print(',');
14077                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14078                    if (ActivityManager.isLowRamDeviceStatic()) {
14079                        pw.print(",low-ram");
14080                    }
14081                    if (ActivityManager.isHighEndGfx()) {
14082                        pw.print(",high-end-gfx");
14083                    }
14084                    pw.println();
14085                }
14086            }
14087        }
14088    }
14089
14090    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14091            long memtrack, String name) {
14092        sb.append("  ");
14093        sb.append(ProcessList.makeOomAdjString(oomAdj));
14094        sb.append(' ');
14095        sb.append(ProcessList.makeProcStateString(procState));
14096        sb.append(' ');
14097        ProcessList.appendRamKb(sb, pss);
14098        sb.append(" kB: ");
14099        sb.append(name);
14100        if (memtrack > 0) {
14101            sb.append(" (");
14102            sb.append(memtrack);
14103            sb.append(" kB memtrack)");
14104        }
14105    }
14106
14107    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14108        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14109        sb.append(" (pid ");
14110        sb.append(mi.pid);
14111        sb.append(") ");
14112        sb.append(mi.adjType);
14113        sb.append('\n');
14114        if (mi.adjReason != null) {
14115            sb.append("                      ");
14116            sb.append(mi.adjReason);
14117            sb.append('\n');
14118        }
14119    }
14120
14121    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14122        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14123        for (int i=0, N=memInfos.size(); i<N; i++) {
14124            ProcessMemInfo mi = memInfos.get(i);
14125            infoMap.put(mi.pid, mi);
14126        }
14127        updateCpuStatsNow();
14128        long[] memtrackTmp = new long[1];
14129        synchronized (mProcessCpuTracker) {
14130            final int N = mProcessCpuTracker.countStats();
14131            for (int i=0; i<N; i++) {
14132                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14133                if (st.vsize > 0) {
14134                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14135                    if (pss > 0) {
14136                        if (infoMap.indexOfKey(st.pid) < 0) {
14137                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14138                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14139                            mi.pss = pss;
14140                            mi.memtrack = memtrackTmp[0];
14141                            memInfos.add(mi);
14142                        }
14143                    }
14144                }
14145            }
14146        }
14147
14148        long totalPss = 0;
14149        long totalMemtrack = 0;
14150        for (int i=0, N=memInfos.size(); i<N; i++) {
14151            ProcessMemInfo mi = memInfos.get(i);
14152            if (mi.pss == 0) {
14153                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14154                mi.memtrack = memtrackTmp[0];
14155            }
14156            totalPss += mi.pss;
14157            totalMemtrack += mi.memtrack;
14158        }
14159        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14160            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14161                if (lhs.oomAdj != rhs.oomAdj) {
14162                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14163                }
14164                if (lhs.pss != rhs.pss) {
14165                    return lhs.pss < rhs.pss ? 1 : -1;
14166                }
14167                return 0;
14168            }
14169        });
14170
14171        StringBuilder tag = new StringBuilder(128);
14172        StringBuilder stack = new StringBuilder(128);
14173        tag.append("Low on memory -- ");
14174        appendMemBucket(tag, totalPss, "total", false);
14175        appendMemBucket(stack, totalPss, "total", true);
14176
14177        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14178        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14179        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14180
14181        boolean firstLine = true;
14182        int lastOomAdj = Integer.MIN_VALUE;
14183        long extraNativeRam = 0;
14184        long extraNativeMemtrack = 0;
14185        long cachedPss = 0;
14186        for (int i=0, N=memInfos.size(); i<N; i++) {
14187            ProcessMemInfo mi = memInfos.get(i);
14188
14189            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14190                cachedPss += mi.pss;
14191            }
14192
14193            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14194                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14195                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14196                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14197                if (lastOomAdj != mi.oomAdj) {
14198                    lastOomAdj = mi.oomAdj;
14199                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14200                        tag.append(" / ");
14201                    }
14202                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14203                        if (firstLine) {
14204                            stack.append(":");
14205                            firstLine = false;
14206                        }
14207                        stack.append("\n\t at ");
14208                    } else {
14209                        stack.append("$");
14210                    }
14211                } else {
14212                    tag.append(" ");
14213                    stack.append("$");
14214                }
14215                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14216                    appendMemBucket(tag, mi.pss, mi.name, false);
14217                }
14218                appendMemBucket(stack, mi.pss, mi.name, true);
14219                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14220                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14221                    stack.append("(");
14222                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14223                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14224                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14225                            stack.append(":");
14226                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14227                        }
14228                    }
14229                    stack.append(")");
14230                }
14231            }
14232
14233            appendMemInfo(fullNativeBuilder, mi);
14234            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14235                // The short form only has native processes that are >= 512K.
14236                if (mi.pss >= 512) {
14237                    appendMemInfo(shortNativeBuilder, mi);
14238                } else {
14239                    extraNativeRam += mi.pss;
14240                    extraNativeMemtrack += mi.memtrack;
14241                }
14242            } else {
14243                // Short form has all other details, but if we have collected RAM
14244                // from smaller native processes let's dump a summary of that.
14245                if (extraNativeRam > 0) {
14246                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14247                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14248                    shortNativeBuilder.append('\n');
14249                    extraNativeRam = 0;
14250                }
14251                appendMemInfo(fullJavaBuilder, mi);
14252            }
14253        }
14254
14255        fullJavaBuilder.append("           ");
14256        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14257        fullJavaBuilder.append(" kB: TOTAL");
14258        if (totalMemtrack > 0) {
14259            fullJavaBuilder.append(" (");
14260            fullJavaBuilder.append(totalMemtrack);
14261            fullJavaBuilder.append(" kB memtrack)");
14262        } else {
14263        }
14264        fullJavaBuilder.append("\n");
14265
14266        MemInfoReader memInfo = new MemInfoReader();
14267        memInfo.readMemInfo();
14268        final long[] infos = memInfo.getRawInfo();
14269
14270        StringBuilder memInfoBuilder = new StringBuilder(1024);
14271        Debug.getMemInfo(infos);
14272        memInfoBuilder.append("  MemInfo: ");
14273        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14274        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14275        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14276        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14277        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14278        memInfoBuilder.append("           ");
14279        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14280        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14281        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14282        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14283        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14284            memInfoBuilder.append("  ZRAM: ");
14285            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14286            memInfoBuilder.append(" kB RAM, ");
14287            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14288            memInfoBuilder.append(" kB swap total, ");
14289            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14290            memInfoBuilder.append(" kB swap free\n");
14291        }
14292        final long[] ksm = getKsmInfo();
14293        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14294                || ksm[KSM_VOLATILE] != 0) {
14295            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14296            memInfoBuilder.append(" kB saved from shared ");
14297            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14298            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14299            memInfoBuilder.append(" kB unshared; ");
14300            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14301        }
14302        memInfoBuilder.append("  Free RAM: ");
14303        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14304                + memInfo.getFreeSizeKb());
14305        memInfoBuilder.append(" kB\n");
14306        memInfoBuilder.append("  Used RAM: ");
14307        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14308        memInfoBuilder.append(" kB\n");
14309        memInfoBuilder.append("  Lost RAM: ");
14310        memInfoBuilder.append(memInfo.getTotalSizeKb()
14311                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14312                - memInfo.getKernelUsedSizeKb());
14313        memInfoBuilder.append(" kB\n");
14314        Slog.i(TAG, "Low on memory:");
14315        Slog.i(TAG, shortNativeBuilder.toString());
14316        Slog.i(TAG, fullJavaBuilder.toString());
14317        Slog.i(TAG, memInfoBuilder.toString());
14318
14319        StringBuilder dropBuilder = new StringBuilder(1024);
14320        /*
14321        StringWriter oomSw = new StringWriter();
14322        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14323        StringWriter catSw = new StringWriter();
14324        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14325        String[] emptyArgs = new String[] { };
14326        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14327        oomPw.flush();
14328        String oomString = oomSw.toString();
14329        */
14330        dropBuilder.append("Low on memory:");
14331        dropBuilder.append(stack);
14332        dropBuilder.append('\n');
14333        dropBuilder.append(fullNativeBuilder);
14334        dropBuilder.append(fullJavaBuilder);
14335        dropBuilder.append('\n');
14336        dropBuilder.append(memInfoBuilder);
14337        dropBuilder.append('\n');
14338        /*
14339        dropBuilder.append(oomString);
14340        dropBuilder.append('\n');
14341        */
14342        StringWriter catSw = new StringWriter();
14343        synchronized (ActivityManagerService.this) {
14344            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14345            String[] emptyArgs = new String[] { };
14346            catPw.println();
14347            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14348            catPw.println();
14349            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14350                    false, false, null);
14351            catPw.println();
14352            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14353            catPw.flush();
14354        }
14355        dropBuilder.append(catSw.toString());
14356        addErrorToDropBox("lowmem", null, "system_server", null,
14357                null, tag.toString(), dropBuilder.toString(), null, null);
14358        //Slog.i(TAG, "Sent to dropbox:");
14359        //Slog.i(TAG, dropBuilder.toString());
14360        synchronized (ActivityManagerService.this) {
14361            long now = SystemClock.uptimeMillis();
14362            if (mLastMemUsageReportTime < now) {
14363                mLastMemUsageReportTime = now;
14364            }
14365        }
14366    }
14367
14368    /**
14369     * Searches array of arguments for the specified string
14370     * @param args array of argument strings
14371     * @param value value to search for
14372     * @return true if the value is contained in the array
14373     */
14374    private static boolean scanArgs(String[] args, String value) {
14375        if (args != null) {
14376            for (String arg : args) {
14377                if (value.equals(arg)) {
14378                    return true;
14379                }
14380            }
14381        }
14382        return false;
14383    }
14384
14385    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14386            ContentProviderRecord cpr, boolean always) {
14387        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14388
14389        if (!inLaunching || always) {
14390            synchronized (cpr) {
14391                cpr.launchingApp = null;
14392                cpr.notifyAll();
14393            }
14394            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14395            String names[] = cpr.info.authority.split(";");
14396            for (int j = 0; j < names.length; j++) {
14397                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14398            }
14399        }
14400
14401        for (int i=0; i<cpr.connections.size(); i++) {
14402            ContentProviderConnection conn = cpr.connections.get(i);
14403            if (conn.waiting) {
14404                // If this connection is waiting for the provider, then we don't
14405                // need to mess with its process unless we are always removing
14406                // or for some reason the provider is not currently launching.
14407                if (inLaunching && !always) {
14408                    continue;
14409                }
14410            }
14411            ProcessRecord capp = conn.client;
14412            conn.dead = true;
14413            if (conn.stableCount > 0) {
14414                if (!capp.persistent && capp.thread != null
14415                        && capp.pid != 0
14416                        && capp.pid != MY_PID) {
14417                    capp.kill("depends on provider "
14418                            + cpr.name.flattenToShortString()
14419                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14420                }
14421            } else if (capp.thread != null && conn.provider.provider != null) {
14422                try {
14423                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14424                } catch (RemoteException e) {
14425                }
14426                // In the protocol here, we don't expect the client to correctly
14427                // clean up this connection, we'll just remove it.
14428                cpr.connections.remove(i);
14429                if (conn.client.conProviders.remove(conn)) {
14430                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14431                }
14432            }
14433        }
14434
14435        if (inLaunching && always) {
14436            mLaunchingProviders.remove(cpr);
14437        }
14438        return inLaunching;
14439    }
14440
14441    /**
14442     * Main code for cleaning up a process when it has gone away.  This is
14443     * called both as a result of the process dying, or directly when stopping
14444     * a process when running in single process mode.
14445     *
14446     * @return Returns true if the given process has been restarted, so the
14447     * app that was passed in must remain on the process lists.
14448     */
14449    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14450            boolean restarting, boolean allowRestart, int index) {
14451        if (index >= 0) {
14452            removeLruProcessLocked(app);
14453            ProcessList.remove(app.pid);
14454        }
14455
14456        mProcessesToGc.remove(app);
14457        mPendingPssProcesses.remove(app);
14458
14459        // Dismiss any open dialogs.
14460        if (app.crashDialog != null && !app.forceCrashReport) {
14461            app.crashDialog.dismiss();
14462            app.crashDialog = null;
14463        }
14464        if (app.anrDialog != null) {
14465            app.anrDialog.dismiss();
14466            app.anrDialog = null;
14467        }
14468        if (app.waitDialog != null) {
14469            app.waitDialog.dismiss();
14470            app.waitDialog = null;
14471        }
14472
14473        app.crashing = false;
14474        app.notResponding = false;
14475
14476        app.resetPackageList(mProcessStats);
14477        app.unlinkDeathRecipient();
14478        app.makeInactive(mProcessStats);
14479        app.waitingToKill = null;
14480        app.forcingToForeground = null;
14481        updateProcessForegroundLocked(app, false, false);
14482        app.foregroundActivities = false;
14483        app.hasShownUi = false;
14484        app.treatLikeActivity = false;
14485        app.hasAboveClient = false;
14486        app.hasClientActivities = false;
14487
14488        mServices.killServicesLocked(app, allowRestart);
14489
14490        boolean restart = false;
14491
14492        // Remove published content providers.
14493        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14494            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14495            final boolean always = app.bad || !allowRestart;
14496            if (removeDyingProviderLocked(app, cpr, always) || always) {
14497                // We left the provider in the launching list, need to
14498                // restart it.
14499                restart = true;
14500            }
14501
14502            cpr.provider = null;
14503            cpr.proc = null;
14504        }
14505        app.pubProviders.clear();
14506
14507        // Take care of any launching providers waiting for this process.
14508        if (checkAppInLaunchingProvidersLocked(app, false)) {
14509            restart = true;
14510        }
14511
14512        // Unregister from connected content providers.
14513        if (!app.conProviders.isEmpty()) {
14514            for (int i=0; i<app.conProviders.size(); i++) {
14515                ContentProviderConnection conn = app.conProviders.get(i);
14516                conn.provider.connections.remove(conn);
14517                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14518                        conn.provider.name);
14519            }
14520            app.conProviders.clear();
14521        }
14522
14523        // At this point there may be remaining entries in mLaunchingProviders
14524        // where we were the only one waiting, so they are no longer of use.
14525        // Look for these and clean up if found.
14526        // XXX Commented out for now.  Trying to figure out a way to reproduce
14527        // the actual situation to identify what is actually going on.
14528        if (false) {
14529            for (int i=0; i<mLaunchingProviders.size(); i++) {
14530                ContentProviderRecord cpr = (ContentProviderRecord)
14531                        mLaunchingProviders.get(i);
14532                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14533                    synchronized (cpr) {
14534                        cpr.launchingApp = null;
14535                        cpr.notifyAll();
14536                    }
14537                }
14538            }
14539        }
14540
14541        skipCurrentReceiverLocked(app);
14542
14543        // Unregister any receivers.
14544        for (int i=app.receivers.size()-1; i>=0; i--) {
14545            removeReceiverLocked(app.receivers.valueAt(i));
14546        }
14547        app.receivers.clear();
14548
14549        // If the app is undergoing backup, tell the backup manager about it
14550        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14551            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14552                    + mBackupTarget.appInfo + " died during backup");
14553            try {
14554                IBackupManager bm = IBackupManager.Stub.asInterface(
14555                        ServiceManager.getService(Context.BACKUP_SERVICE));
14556                bm.agentDisconnected(app.info.packageName);
14557            } catch (RemoteException e) {
14558                // can't happen; backup manager is local
14559            }
14560        }
14561
14562        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14563            ProcessChangeItem item = mPendingProcessChanges.get(i);
14564            if (item.pid == app.pid) {
14565                mPendingProcessChanges.remove(i);
14566                mAvailProcessChanges.add(item);
14567            }
14568        }
14569        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14570
14571        // If the caller is restarting this app, then leave it in its
14572        // current lists and let the caller take care of it.
14573        if (restarting) {
14574            return false;
14575        }
14576
14577        if (!app.persistent || app.isolated) {
14578            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14579                    "Removing non-persistent process during cleanup: " + app);
14580            mProcessNames.remove(app.processName, app.uid);
14581            mIsolatedProcesses.remove(app.uid);
14582            if (mHeavyWeightProcess == app) {
14583                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14584                        mHeavyWeightProcess.userId, 0));
14585                mHeavyWeightProcess = null;
14586            }
14587        } else if (!app.removed) {
14588            // This app is persistent, so we need to keep its record around.
14589            // If it is not already on the pending app list, add it there
14590            // and start a new process for it.
14591            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14592                mPersistentStartingProcesses.add(app);
14593                restart = true;
14594            }
14595        }
14596        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14597                "Clean-up removing on hold: " + app);
14598        mProcessesOnHold.remove(app);
14599
14600        if (app == mHomeProcess) {
14601            mHomeProcess = null;
14602        }
14603        if (app == mPreviousProcess) {
14604            mPreviousProcess = null;
14605        }
14606
14607        if (restart && !app.isolated) {
14608            // We have components that still need to be running in the
14609            // process, so re-launch it.
14610            if (index < 0) {
14611                ProcessList.remove(app.pid);
14612            }
14613            mProcessNames.put(app.processName, app.uid, app);
14614            startProcessLocked(app, "restart", app.processName);
14615            return true;
14616        } else if (app.pid > 0 && app.pid != MY_PID) {
14617            // Goodbye!
14618            boolean removed;
14619            synchronized (mPidsSelfLocked) {
14620                mPidsSelfLocked.remove(app.pid);
14621                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14622            }
14623            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14624            if (app.isolated) {
14625                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14626            }
14627            app.setPid(0);
14628        }
14629        return false;
14630    }
14631
14632    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14633        // Look through the content providers we are waiting to have launched,
14634        // and if any run in this process then either schedule a restart of
14635        // the process or kill the client waiting for it if this process has
14636        // gone bad.
14637        int NL = mLaunchingProviders.size();
14638        boolean restart = false;
14639        for (int i=0; i<NL; i++) {
14640            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14641            if (cpr.launchingApp == app) {
14642                if (!alwaysBad && !app.bad) {
14643                    restart = true;
14644                } else {
14645                    removeDyingProviderLocked(app, cpr, true);
14646                    // cpr should have been removed from mLaunchingProviders
14647                    NL = mLaunchingProviders.size();
14648                    i--;
14649                }
14650            }
14651        }
14652        return restart;
14653    }
14654
14655    // =========================================================
14656    // SERVICES
14657    // =========================================================
14658
14659    @Override
14660    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14661            int flags) {
14662        enforceNotIsolatedCaller("getServices");
14663        synchronized (this) {
14664            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14665        }
14666    }
14667
14668    @Override
14669    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14670        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14671        synchronized (this) {
14672            return mServices.getRunningServiceControlPanelLocked(name);
14673        }
14674    }
14675
14676    @Override
14677    public ComponentName startService(IApplicationThread caller, Intent service,
14678            String resolvedType, int userId) {
14679        enforceNotIsolatedCaller("startService");
14680        // Refuse possible leaked file descriptors
14681        if (service != null && service.hasFileDescriptors() == true) {
14682            throw new IllegalArgumentException("File descriptors passed in Intent");
14683        }
14684
14685        if (DEBUG_SERVICE)
14686            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14687        synchronized(this) {
14688            final int callingPid = Binder.getCallingPid();
14689            final int callingUid = Binder.getCallingUid();
14690            final long origId = Binder.clearCallingIdentity();
14691            ComponentName res = mServices.startServiceLocked(caller, service,
14692                    resolvedType, callingPid, callingUid, userId);
14693            Binder.restoreCallingIdentity(origId);
14694            return res;
14695        }
14696    }
14697
14698    ComponentName startServiceInPackage(int uid,
14699            Intent service, String resolvedType, int userId) {
14700        synchronized(this) {
14701            if (DEBUG_SERVICE)
14702                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14703            final long origId = Binder.clearCallingIdentity();
14704            ComponentName res = mServices.startServiceLocked(null, service,
14705                    resolvedType, -1, uid, userId);
14706            Binder.restoreCallingIdentity(origId);
14707            return res;
14708        }
14709    }
14710
14711    @Override
14712    public int stopService(IApplicationThread caller, Intent service,
14713            String resolvedType, int userId) {
14714        enforceNotIsolatedCaller("stopService");
14715        // Refuse possible leaked file descriptors
14716        if (service != null && service.hasFileDescriptors() == true) {
14717            throw new IllegalArgumentException("File descriptors passed in Intent");
14718        }
14719
14720        synchronized(this) {
14721            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14722        }
14723    }
14724
14725    @Override
14726    public IBinder peekService(Intent service, String resolvedType) {
14727        enforceNotIsolatedCaller("peekService");
14728        // Refuse possible leaked file descriptors
14729        if (service != null && service.hasFileDescriptors() == true) {
14730            throw new IllegalArgumentException("File descriptors passed in Intent");
14731        }
14732        synchronized(this) {
14733            return mServices.peekServiceLocked(service, resolvedType);
14734        }
14735    }
14736
14737    @Override
14738    public boolean stopServiceToken(ComponentName className, IBinder token,
14739            int startId) {
14740        synchronized(this) {
14741            return mServices.stopServiceTokenLocked(className, token, startId);
14742        }
14743    }
14744
14745    @Override
14746    public void setServiceForeground(ComponentName className, IBinder token,
14747            int id, Notification notification, boolean removeNotification) {
14748        synchronized(this) {
14749            mServices.setServiceForegroundLocked(className, token, id, notification,
14750                    removeNotification);
14751        }
14752    }
14753
14754    @Override
14755    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14756            boolean requireFull, String name, String callerPackage) {
14757        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14758                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14759    }
14760
14761    int unsafeConvertIncomingUser(int userId) {
14762        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14763                ? mCurrentUserId : userId;
14764    }
14765
14766    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14767            int allowMode, String name, String callerPackage) {
14768        final int callingUserId = UserHandle.getUserId(callingUid);
14769        if (callingUserId == userId) {
14770            return userId;
14771        }
14772
14773        // Note that we may be accessing mCurrentUserId outside of a lock...
14774        // shouldn't be a big deal, if this is being called outside
14775        // of a locked context there is intrinsically a race with
14776        // the value the caller will receive and someone else changing it.
14777        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14778        // we will switch to the calling user if access to the current user fails.
14779        int targetUserId = unsafeConvertIncomingUser(userId);
14780
14781        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14782            final boolean allow;
14783            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14784                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14785                // If the caller has this permission, they always pass go.  And collect $200.
14786                allow = true;
14787            } else if (allowMode == ALLOW_FULL_ONLY) {
14788                // We require full access, sucks to be you.
14789                allow = false;
14790            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14791                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14792                // If the caller does not have either permission, they are always doomed.
14793                allow = false;
14794            } else if (allowMode == ALLOW_NON_FULL) {
14795                // We are blanket allowing non-full access, you lucky caller!
14796                allow = true;
14797            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14798                // We may or may not allow this depending on whether the two users are
14799                // in the same profile.
14800                synchronized (mUserProfileGroupIdsSelfLocked) {
14801                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14802                            UserInfo.NO_PROFILE_GROUP_ID);
14803                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14804                            UserInfo.NO_PROFILE_GROUP_ID);
14805                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14806                            && callingProfile == targetProfile;
14807                }
14808            } else {
14809                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14810            }
14811            if (!allow) {
14812                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14813                    // In this case, they would like to just execute as their
14814                    // owner user instead of failing.
14815                    targetUserId = callingUserId;
14816                } else {
14817                    StringBuilder builder = new StringBuilder(128);
14818                    builder.append("Permission Denial: ");
14819                    builder.append(name);
14820                    if (callerPackage != null) {
14821                        builder.append(" from ");
14822                        builder.append(callerPackage);
14823                    }
14824                    builder.append(" asks to run as user ");
14825                    builder.append(userId);
14826                    builder.append(" but is calling from user ");
14827                    builder.append(UserHandle.getUserId(callingUid));
14828                    builder.append("; this requires ");
14829                    builder.append(INTERACT_ACROSS_USERS_FULL);
14830                    if (allowMode != ALLOW_FULL_ONLY) {
14831                        builder.append(" or ");
14832                        builder.append(INTERACT_ACROSS_USERS);
14833                    }
14834                    String msg = builder.toString();
14835                    Slog.w(TAG, msg);
14836                    throw new SecurityException(msg);
14837                }
14838            }
14839        }
14840        if (!allowAll && targetUserId < 0) {
14841            throw new IllegalArgumentException(
14842                    "Call does not support special user #" + targetUserId);
14843        }
14844        // Check shell permission
14845        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14846            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14847                    targetUserId)) {
14848                throw new SecurityException("Shell does not have permission to access user "
14849                        + targetUserId + "\n " + Debug.getCallers(3));
14850            }
14851        }
14852        return targetUserId;
14853    }
14854
14855    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14856            String className, int flags) {
14857        boolean result = false;
14858        // For apps that don't have pre-defined UIDs, check for permission
14859        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14860            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14861                if (ActivityManager.checkUidPermission(
14862                        INTERACT_ACROSS_USERS,
14863                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14864                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14865                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14866                            + " requests FLAG_SINGLE_USER, but app does not hold "
14867                            + INTERACT_ACROSS_USERS;
14868                    Slog.w(TAG, msg);
14869                    throw new SecurityException(msg);
14870                }
14871                // Permission passed
14872                result = true;
14873            }
14874        } else if ("system".equals(componentProcessName)) {
14875            result = true;
14876        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14877            // Phone app and persistent apps are allowed to export singleuser providers.
14878            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14879                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14880        }
14881        if (DEBUG_MU) {
14882            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14883                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14884        }
14885        return result;
14886    }
14887
14888    /**
14889     * Checks to see if the caller is in the same app as the singleton
14890     * component, or the component is in a special app. It allows special apps
14891     * to export singleton components but prevents exporting singleton
14892     * components for regular apps.
14893     */
14894    boolean isValidSingletonCall(int callingUid, int componentUid) {
14895        int componentAppId = UserHandle.getAppId(componentUid);
14896        return UserHandle.isSameApp(callingUid, componentUid)
14897                || componentAppId == Process.SYSTEM_UID
14898                || componentAppId == Process.PHONE_UID
14899                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14900                        == PackageManager.PERMISSION_GRANTED;
14901    }
14902
14903    public int bindService(IApplicationThread caller, IBinder token,
14904            Intent service, String resolvedType,
14905            IServiceConnection connection, int flags, int userId) {
14906        enforceNotIsolatedCaller("bindService");
14907
14908        // Refuse possible leaked file descriptors
14909        if (service != null && service.hasFileDescriptors() == true) {
14910            throw new IllegalArgumentException("File descriptors passed in Intent");
14911        }
14912
14913        synchronized(this) {
14914            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14915                    connection, flags, userId);
14916        }
14917    }
14918
14919    public boolean unbindService(IServiceConnection connection) {
14920        synchronized (this) {
14921            return mServices.unbindServiceLocked(connection);
14922        }
14923    }
14924
14925    public void publishService(IBinder token, Intent intent, IBinder service) {
14926        // Refuse possible leaked file descriptors
14927        if (intent != null && intent.hasFileDescriptors() == true) {
14928            throw new IllegalArgumentException("File descriptors passed in Intent");
14929        }
14930
14931        synchronized(this) {
14932            if (!(token instanceof ServiceRecord)) {
14933                throw new IllegalArgumentException("Invalid service token");
14934            }
14935            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14936        }
14937    }
14938
14939    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14940        // Refuse possible leaked file descriptors
14941        if (intent != null && intent.hasFileDescriptors() == true) {
14942            throw new IllegalArgumentException("File descriptors passed in Intent");
14943        }
14944
14945        synchronized(this) {
14946            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14947        }
14948    }
14949
14950    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14951        synchronized(this) {
14952            if (!(token instanceof ServiceRecord)) {
14953                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
14954                throw new IllegalArgumentException("Invalid service token");
14955            }
14956            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14957        }
14958    }
14959
14960    // =========================================================
14961    // BACKUP AND RESTORE
14962    // =========================================================
14963
14964    // Cause the target app to be launched if necessary and its backup agent
14965    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14966    // activity manager to announce its creation.
14967    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14968        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14969        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14970
14971        synchronized(this) {
14972            // !!! TODO: currently no check here that we're already bound
14973            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14974            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14975            synchronized (stats) {
14976                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14977            }
14978
14979            // Backup agent is now in use, its package can't be stopped.
14980            try {
14981                AppGlobals.getPackageManager().setPackageStoppedState(
14982                        app.packageName, false, UserHandle.getUserId(app.uid));
14983            } catch (RemoteException e) {
14984            } catch (IllegalArgumentException e) {
14985                Slog.w(TAG, "Failed trying to unstop package "
14986                        + app.packageName + ": " + e);
14987            }
14988
14989            BackupRecord r = new BackupRecord(ss, app, backupMode);
14990            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14991                    ? new ComponentName(app.packageName, app.backupAgentName)
14992                    : new ComponentName("android", "FullBackupAgent");
14993            // startProcessLocked() returns existing proc's record if it's already running
14994            ProcessRecord proc = startProcessLocked(app.processName, app,
14995                    false, 0, "backup", hostingName, false, false, false);
14996            if (proc == null) {
14997                Slog.e(TAG, "Unable to start backup agent process " + r);
14998                return false;
14999            }
15000
15001            r.app = proc;
15002            mBackupTarget = r;
15003            mBackupAppName = app.packageName;
15004
15005            // Try not to kill the process during backup
15006            updateOomAdjLocked(proc);
15007
15008            // If the process is already attached, schedule the creation of the backup agent now.
15009            // If it is not yet live, this will be done when it attaches to the framework.
15010            if (proc.thread != null) {
15011                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15012                try {
15013                    proc.thread.scheduleCreateBackupAgent(app,
15014                            compatibilityInfoForPackageLocked(app), backupMode);
15015                } catch (RemoteException e) {
15016                    // Will time out on the backup manager side
15017                }
15018            } else {
15019                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15020            }
15021            // Invariants: at this point, the target app process exists and the application
15022            // is either already running or in the process of coming up.  mBackupTarget and
15023            // mBackupAppName describe the app, so that when it binds back to the AM we
15024            // know that it's scheduled for a backup-agent operation.
15025        }
15026
15027        return true;
15028    }
15029
15030    @Override
15031    public void clearPendingBackup() {
15032        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15033        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15034
15035        synchronized (this) {
15036            mBackupTarget = null;
15037            mBackupAppName = null;
15038        }
15039    }
15040
15041    // A backup agent has just come up
15042    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15043        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15044                + " = " + agent);
15045
15046        synchronized(this) {
15047            if (!agentPackageName.equals(mBackupAppName)) {
15048                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15049                return;
15050            }
15051        }
15052
15053        long oldIdent = Binder.clearCallingIdentity();
15054        try {
15055            IBackupManager bm = IBackupManager.Stub.asInterface(
15056                    ServiceManager.getService(Context.BACKUP_SERVICE));
15057            bm.agentConnected(agentPackageName, agent);
15058        } catch (RemoteException e) {
15059            // can't happen; the backup manager service is local
15060        } catch (Exception e) {
15061            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15062            e.printStackTrace();
15063        } finally {
15064            Binder.restoreCallingIdentity(oldIdent);
15065        }
15066    }
15067
15068    // done with this agent
15069    public void unbindBackupAgent(ApplicationInfo appInfo) {
15070        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15071        if (appInfo == null) {
15072            Slog.w(TAG, "unbind backup agent for null app");
15073            return;
15074        }
15075
15076        synchronized(this) {
15077            try {
15078                if (mBackupAppName == null) {
15079                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15080                    return;
15081                }
15082
15083                if (!mBackupAppName.equals(appInfo.packageName)) {
15084                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15085                    return;
15086                }
15087
15088                // Not backing this app up any more; reset its OOM adjustment
15089                final ProcessRecord proc = mBackupTarget.app;
15090                updateOomAdjLocked(proc);
15091
15092                // If the app crashed during backup, 'thread' will be null here
15093                if (proc.thread != null) {
15094                    try {
15095                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15096                                compatibilityInfoForPackageLocked(appInfo));
15097                    } catch (Exception e) {
15098                        Slog.e(TAG, "Exception when unbinding backup agent:");
15099                        e.printStackTrace();
15100                    }
15101                }
15102            } finally {
15103                mBackupTarget = null;
15104                mBackupAppName = null;
15105            }
15106        }
15107    }
15108    // =========================================================
15109    // BROADCASTS
15110    // =========================================================
15111
15112    boolean isPendingBroadcastProcessLocked(int pid) {
15113        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15114                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15115    }
15116
15117    void skipPendingBroadcastLocked(int pid) {
15118            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15119            for (BroadcastQueue queue : mBroadcastQueues) {
15120                queue.skipPendingBroadcastLocked(pid);
15121            }
15122    }
15123
15124    // The app just attached; send any pending broadcasts that it should receive
15125    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15126        boolean didSomething = false;
15127        for (BroadcastQueue queue : mBroadcastQueues) {
15128            didSomething |= queue.sendPendingBroadcastsLocked(app);
15129        }
15130        return didSomething;
15131    }
15132
15133    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15134            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15135        enforceNotIsolatedCaller("registerReceiver");
15136        ArrayList<Intent> stickyIntents = null;
15137        ProcessRecord callerApp = null;
15138        int callingUid;
15139        int callingPid;
15140        synchronized(this) {
15141            if (caller != null) {
15142                callerApp = getRecordForAppLocked(caller);
15143                if (callerApp == null) {
15144                    throw new SecurityException(
15145                            "Unable to find app for caller " + caller
15146                            + " (pid=" + Binder.getCallingPid()
15147                            + ") when registering receiver " + receiver);
15148                }
15149                if (callerApp.info.uid != Process.SYSTEM_UID &&
15150                        !callerApp.pkgList.containsKey(callerPackage) &&
15151                        !"android".equals(callerPackage)) {
15152                    throw new SecurityException("Given caller package " + callerPackage
15153                            + " is not running in process " + callerApp);
15154                }
15155                callingUid = callerApp.info.uid;
15156                callingPid = callerApp.pid;
15157            } else {
15158                callerPackage = null;
15159                callingUid = Binder.getCallingUid();
15160                callingPid = Binder.getCallingPid();
15161            }
15162
15163            userId = handleIncomingUser(callingPid, callingUid, userId,
15164                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15165
15166            Iterator<String> actions = filter.actionsIterator();
15167            if (actions == null) {
15168                ArrayList<String> noAction = new ArrayList<String>(1);
15169                noAction.add(null);
15170                actions = noAction.iterator();
15171            }
15172
15173            // Collect stickies of users
15174            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15175            while (actions.hasNext()) {
15176                String action = actions.next();
15177                for (int id : userIds) {
15178                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15179                    if (stickies != null) {
15180                        ArrayList<Intent> intents = stickies.get(action);
15181                        if (intents != null) {
15182                            if (stickyIntents == null) {
15183                                stickyIntents = new ArrayList<Intent>();
15184                            }
15185                            stickyIntents.addAll(intents);
15186                        }
15187                    }
15188                }
15189            }
15190        }
15191
15192        ArrayList<Intent> allSticky = null;
15193        if (stickyIntents != null) {
15194            final ContentResolver resolver = mContext.getContentResolver();
15195            // Look for any matching sticky broadcasts...
15196            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15197                Intent intent = stickyIntents.get(i);
15198                // If intent has scheme "content", it will need to acccess
15199                // provider that needs to lock mProviderMap in ActivityThread
15200                // and also it may need to wait application response, so we
15201                // cannot lock ActivityManagerService here.
15202                if (filter.match(resolver, intent, true, TAG) >= 0) {
15203                    if (allSticky == null) {
15204                        allSticky = new ArrayList<Intent>();
15205                    }
15206                    allSticky.add(intent);
15207                }
15208            }
15209        }
15210
15211        // The first sticky in the list is returned directly back to the client.
15212        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15213        if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky);
15214        if (receiver == null) {
15215            return sticky;
15216        }
15217
15218        synchronized (this) {
15219            if (callerApp != null && callerApp.pid == 0) {
15220                // Caller already died
15221                return null;
15222            }
15223            ReceiverList rl
15224                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15225            if (rl == null) {
15226                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15227                        userId, receiver);
15228                if (rl.app != null) {
15229                    rl.app.receivers.add(rl);
15230                } else {
15231                    try {
15232                        receiver.asBinder().linkToDeath(rl, 0);
15233                    } catch (RemoteException e) {
15234                        return sticky;
15235                    }
15236                    rl.linkedToDeath = true;
15237                }
15238                mRegisteredReceivers.put(receiver.asBinder(), rl);
15239            } else if (rl.uid != callingUid) {
15240                throw new IllegalArgumentException(
15241                        "Receiver requested to register for uid " + callingUid
15242                        + " was previously registered for uid " + rl.uid);
15243            } else if (rl.pid != callingPid) {
15244                throw new IllegalArgumentException(
15245                        "Receiver requested to register for pid " + callingPid
15246                        + " was previously registered for pid " + rl.pid);
15247            } else if (rl.userId != userId) {
15248                throw new IllegalArgumentException(
15249                        "Receiver requested to register for user " + userId
15250                        + " was previously registered for user " + rl.userId);
15251            }
15252            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15253                    permission, callingUid, userId);
15254            rl.add(bf);
15255            if (!bf.debugCheck()) {
15256                Slog.w(TAG, "==> For Dynamic broadast");
15257            }
15258            mReceiverResolver.addFilter(bf);
15259
15260            // Enqueue broadcasts for all existing stickies that match
15261            // this filter.
15262            if (allSticky != null) {
15263                ArrayList receivers = new ArrayList();
15264                receivers.add(bf);
15265
15266                int N = allSticky.size();
15267                for (int i=0; i<N; i++) {
15268                    Intent intent = (Intent)allSticky.get(i);
15269                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15270                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15271                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15272                            null, null, false, true, true, -1);
15273                    queue.enqueueParallelBroadcastLocked(r);
15274                    queue.scheduleBroadcastsLocked();
15275                }
15276            }
15277
15278            return sticky;
15279        }
15280    }
15281
15282    public void unregisterReceiver(IIntentReceiver receiver) {
15283        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15284
15285        final long origId = Binder.clearCallingIdentity();
15286        try {
15287            boolean doTrim = false;
15288
15289            synchronized(this) {
15290                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15291                if (rl != null) {
15292                    final BroadcastRecord r = rl.curBroadcast;
15293                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15294                        final boolean doNext = r.queue.finishReceiverLocked(
15295                                r, r.resultCode, r.resultData, r.resultExtras,
15296                                r.resultAbort, false);
15297                        if (doNext) {
15298                            doTrim = true;
15299                            r.queue.processNextBroadcast(false);
15300                        }
15301                    }
15302
15303                    if (rl.app != null) {
15304                        rl.app.receivers.remove(rl);
15305                    }
15306                    removeReceiverLocked(rl);
15307                    if (rl.linkedToDeath) {
15308                        rl.linkedToDeath = false;
15309                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15310                    }
15311                }
15312            }
15313
15314            // If we actually concluded any broadcasts, we might now be able
15315            // to trim the recipients' apps from our working set
15316            if (doTrim) {
15317                trimApplications();
15318                return;
15319            }
15320
15321        } finally {
15322            Binder.restoreCallingIdentity(origId);
15323        }
15324    }
15325
15326    void removeReceiverLocked(ReceiverList rl) {
15327        mRegisteredReceivers.remove(rl.receiver.asBinder());
15328        int N = rl.size();
15329        for (int i=0; i<N; i++) {
15330            mReceiverResolver.removeFilter(rl.get(i));
15331        }
15332    }
15333
15334    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15335        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15336            ProcessRecord r = mLruProcesses.get(i);
15337            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15338                try {
15339                    r.thread.dispatchPackageBroadcast(cmd, packages);
15340                } catch (RemoteException ex) {
15341                }
15342            }
15343        }
15344    }
15345
15346    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15347            int callingUid, int[] users) {
15348        List<ResolveInfo> receivers = null;
15349        try {
15350            HashSet<ComponentName> singleUserReceivers = null;
15351            boolean scannedFirstReceivers = false;
15352            for (int user : users) {
15353                // Skip users that have Shell restrictions
15354                if (callingUid == Process.SHELL_UID
15355                        && getUserManagerLocked().hasUserRestriction(
15356                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15357                    continue;
15358                }
15359                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15360                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15361                if (user != 0 && newReceivers != null) {
15362                    // If this is not the primary user, we need to check for
15363                    // any receivers that should be filtered out.
15364                    for (int i=0; i<newReceivers.size(); i++) {
15365                        ResolveInfo ri = newReceivers.get(i);
15366                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15367                            newReceivers.remove(i);
15368                            i--;
15369                        }
15370                    }
15371                }
15372                if (newReceivers != null && newReceivers.size() == 0) {
15373                    newReceivers = null;
15374                }
15375                if (receivers == null) {
15376                    receivers = newReceivers;
15377                } else if (newReceivers != null) {
15378                    // We need to concatenate the additional receivers
15379                    // found with what we have do far.  This would be easy,
15380                    // but we also need to de-dup any receivers that are
15381                    // singleUser.
15382                    if (!scannedFirstReceivers) {
15383                        // Collect any single user receivers we had already retrieved.
15384                        scannedFirstReceivers = true;
15385                        for (int i=0; i<receivers.size(); i++) {
15386                            ResolveInfo ri = receivers.get(i);
15387                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15388                                ComponentName cn = new ComponentName(
15389                                        ri.activityInfo.packageName, ri.activityInfo.name);
15390                                if (singleUserReceivers == null) {
15391                                    singleUserReceivers = new HashSet<ComponentName>();
15392                                }
15393                                singleUserReceivers.add(cn);
15394                            }
15395                        }
15396                    }
15397                    // Add the new results to the existing results, tracking
15398                    // and de-dupping single user receivers.
15399                    for (int i=0; i<newReceivers.size(); i++) {
15400                        ResolveInfo ri = newReceivers.get(i);
15401                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15402                            ComponentName cn = new ComponentName(
15403                                    ri.activityInfo.packageName, ri.activityInfo.name);
15404                            if (singleUserReceivers == null) {
15405                                singleUserReceivers = new HashSet<ComponentName>();
15406                            }
15407                            if (!singleUserReceivers.contains(cn)) {
15408                                singleUserReceivers.add(cn);
15409                                receivers.add(ri);
15410                            }
15411                        } else {
15412                            receivers.add(ri);
15413                        }
15414                    }
15415                }
15416            }
15417        } catch (RemoteException ex) {
15418            // pm is in same process, this will never happen.
15419        }
15420        return receivers;
15421    }
15422
15423    private final int broadcastIntentLocked(ProcessRecord callerApp,
15424            String callerPackage, Intent intent, String resolvedType,
15425            IIntentReceiver resultTo, int resultCode, String resultData,
15426            Bundle map, String requiredPermission, int appOp,
15427            boolean ordered, boolean sticky, int callingPid, int callingUid,
15428            int userId) {
15429        intent = new Intent(intent);
15430
15431        // By default broadcasts do not go to stopped apps.
15432        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15433
15434        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15435            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15436            + " ordered=" + ordered + " userid=" + userId);
15437        if ((resultTo != null) && !ordered) {
15438            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15439        }
15440
15441        userId = handleIncomingUser(callingPid, callingUid, userId,
15442                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15443
15444        // Make sure that the user who is receiving this broadcast is running.
15445        // If not, we will just skip it. Make an exception for shutdown broadcasts
15446        // and upgrade steps.
15447
15448        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15449            if ((callingUid != Process.SYSTEM_UID
15450                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15451                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15452                Slog.w(TAG, "Skipping broadcast of " + intent
15453                        + ": user " + userId + " is stopped");
15454                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15455            }
15456        }
15457
15458        /*
15459         * Prevent non-system code (defined here to be non-persistent
15460         * processes) from sending protected broadcasts.
15461         */
15462        int callingAppId = UserHandle.getAppId(callingUid);
15463        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15464            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15465            || callingAppId == Process.NFC_UID || callingUid == 0) {
15466            // Always okay.
15467        } else if (callerApp == null || !callerApp.persistent) {
15468            try {
15469                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15470                        intent.getAction())) {
15471                    String msg = "Permission Denial: not allowed to send broadcast "
15472                            + intent.getAction() + " from pid="
15473                            + callingPid + ", uid=" + callingUid;
15474                    Slog.w(TAG, msg);
15475                    throw new SecurityException(msg);
15476                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15477                    // Special case for compatibility: we don't want apps to send this,
15478                    // but historically it has not been protected and apps may be using it
15479                    // to poke their own app widget.  So, instead of making it protected,
15480                    // just limit it to the caller.
15481                    if (callerApp == null) {
15482                        String msg = "Permission Denial: not allowed to send broadcast "
15483                                + intent.getAction() + " from unknown caller.";
15484                        Slog.w(TAG, msg);
15485                        throw new SecurityException(msg);
15486                    } else if (intent.getComponent() != null) {
15487                        // They are good enough to send to an explicit component...  verify
15488                        // it is being sent to the calling app.
15489                        if (!intent.getComponent().getPackageName().equals(
15490                                callerApp.info.packageName)) {
15491                            String msg = "Permission Denial: not allowed to send broadcast "
15492                                    + intent.getAction() + " to "
15493                                    + intent.getComponent().getPackageName() + " from "
15494                                    + callerApp.info.packageName;
15495                            Slog.w(TAG, msg);
15496                            throw new SecurityException(msg);
15497                        }
15498                    } else {
15499                        // Limit broadcast to their own package.
15500                        intent.setPackage(callerApp.info.packageName);
15501                    }
15502                }
15503            } catch (RemoteException e) {
15504                Slog.w(TAG, "Remote exception", e);
15505                return ActivityManager.BROADCAST_SUCCESS;
15506            }
15507        }
15508
15509        final String action = intent.getAction();
15510        if (action != null) {
15511            switch (action) {
15512                case Intent.ACTION_UID_REMOVED:
15513                case Intent.ACTION_PACKAGE_REMOVED:
15514                case Intent.ACTION_PACKAGE_CHANGED:
15515                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15516                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15517                    // Handle special intents: if this broadcast is from the package
15518                    // manager about a package being removed, we need to remove all of
15519                    // its activities from the history stack.
15520                    if (checkComponentPermission(
15521                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15522                            callingPid, callingUid, -1, true)
15523                            != PackageManager.PERMISSION_GRANTED) {
15524                        String msg = "Permission Denial: " + intent.getAction()
15525                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15526                                + ", uid=" + callingUid + ")"
15527                                + " requires "
15528                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15529                        Slog.w(TAG, msg);
15530                        throw new SecurityException(msg);
15531                    }
15532                    switch (action) {
15533                        case Intent.ACTION_UID_REMOVED:
15534                            final Bundle intentExtras = intent.getExtras();
15535                            final int uid = intentExtras != null
15536                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15537                            if (uid >= 0) {
15538                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15539                                synchronized (bs) {
15540                                    bs.removeUidStatsLocked(uid);
15541                                }
15542                                mAppOpsService.uidRemoved(uid);
15543                            }
15544                            break;
15545                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15546                            // If resources are unavailable just force stop all those packages
15547                            // and flush the attribute cache as well.
15548                            String list[] =
15549                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15550                            if (list != null && list.length > 0) {
15551                                for (int i = 0; i < list.length; i++) {
15552                                    forceStopPackageLocked(list[i], -1, false, true, true,
15553                                            false, false, userId, "storage unmount");
15554                                }
15555                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15556                                sendPackageBroadcastLocked(
15557                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15558                                        userId);
15559                            }
15560                            break;
15561                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15562                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15563                            break;
15564                        case Intent.ACTION_PACKAGE_REMOVED:
15565                        case Intent.ACTION_PACKAGE_CHANGED:
15566                            Uri data = intent.getData();
15567                            String ssp;
15568                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15569                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15570                                boolean fullUninstall = removed &&
15571                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15572                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15573                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15574                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15575                                            false, true, true, false, fullUninstall, userId,
15576                                            removed ? "pkg removed" : "pkg changed");
15577                                }
15578                                if (removed) {
15579                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15580                                            new String[] {ssp}, userId);
15581                                    if (fullUninstall) {
15582                                        mAppOpsService.packageRemoved(
15583                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15584
15585                                        // Remove all permissions granted from/to this package
15586                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15587
15588                                        removeTasksByPackageNameLocked(ssp, userId);
15589                                        if (userId == UserHandle.USER_OWNER) {
15590                                            mTaskPersister.removeFromPackageCache(ssp);
15591                                        }
15592                                    }
15593                                } else {
15594                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15595                                    if (userId == UserHandle.USER_OWNER) {
15596                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15597                                    }
15598                                }
15599                            }
15600                            break;
15601                    }
15602                    break;
15603                case Intent.ACTION_PACKAGE_ADDED:
15604                    // Special case for adding a package: by default turn on compatibility mode.
15605                    Uri data = intent.getData();
15606                    String ssp;
15607                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15608                        final boolean replacing =
15609                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15610                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15611
15612                        if (replacing) {
15613                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15614                        }
15615                        if (userId == UserHandle.USER_OWNER) {
15616                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15617                        }
15618                    }
15619                    break;
15620                case Intent.ACTION_TIMEZONE_CHANGED:
15621                    // If this is the time zone changed action, queue up a message that will reset
15622                    // the timezone of all currently running processes. This message will get
15623                    // queued up before the broadcast happens.
15624                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15625                    break;
15626                case Intent.ACTION_TIME_CHANGED:
15627                    // If the user set the time, let all running processes know.
15628                    final int is24Hour =
15629                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15630                                    : 0;
15631                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15632                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15633                    synchronized (stats) {
15634                        stats.noteCurrentTimeChangedLocked();
15635                    }
15636                    break;
15637                case Intent.ACTION_CLEAR_DNS_CACHE:
15638                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15639                    break;
15640                case Proxy.PROXY_CHANGE_ACTION:
15641                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15642                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15643                    break;
15644            }
15645        }
15646
15647        // Add to the sticky list if requested.
15648        if (sticky) {
15649            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15650                    callingPid, callingUid)
15651                    != PackageManager.PERMISSION_GRANTED) {
15652                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15653                        + callingPid + ", uid=" + callingUid
15654                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15655                Slog.w(TAG, msg);
15656                throw new SecurityException(msg);
15657            }
15658            if (requiredPermission != null) {
15659                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15660                        + " and enforce permission " + requiredPermission);
15661                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15662            }
15663            if (intent.getComponent() != null) {
15664                throw new SecurityException(
15665                        "Sticky broadcasts can't target a specific component");
15666            }
15667            // We use userId directly here, since the "all" target is maintained
15668            // as a separate set of sticky broadcasts.
15669            if (userId != UserHandle.USER_ALL) {
15670                // But first, if this is not a broadcast to all users, then
15671                // make sure it doesn't conflict with an existing broadcast to
15672                // all users.
15673                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15674                        UserHandle.USER_ALL);
15675                if (stickies != null) {
15676                    ArrayList<Intent> list = stickies.get(intent.getAction());
15677                    if (list != null) {
15678                        int N = list.size();
15679                        int i;
15680                        for (i=0; i<N; i++) {
15681                            if (intent.filterEquals(list.get(i))) {
15682                                throw new IllegalArgumentException(
15683                                        "Sticky broadcast " + intent + " for user "
15684                                        + userId + " conflicts with existing global broadcast");
15685                            }
15686                        }
15687                    }
15688                }
15689            }
15690            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15691            if (stickies == null) {
15692                stickies = new ArrayMap<String, ArrayList<Intent>>();
15693                mStickyBroadcasts.put(userId, stickies);
15694            }
15695            ArrayList<Intent> list = stickies.get(intent.getAction());
15696            if (list == null) {
15697                list = new ArrayList<Intent>();
15698                stickies.put(intent.getAction(), list);
15699            }
15700            int N = list.size();
15701            int i;
15702            for (i=0; i<N; i++) {
15703                if (intent.filterEquals(list.get(i))) {
15704                    // This sticky already exists, replace it.
15705                    list.set(i, new Intent(intent));
15706                    break;
15707                }
15708            }
15709            if (i >= N) {
15710                list.add(new Intent(intent));
15711            }
15712        }
15713
15714        int[] users;
15715        if (userId == UserHandle.USER_ALL) {
15716            // Caller wants broadcast to go to all started users.
15717            users = mStartedUserArray;
15718        } else {
15719            // Caller wants broadcast to go to one specific user.
15720            users = new int[] {userId};
15721        }
15722
15723        // Figure out who all will receive this broadcast.
15724        List receivers = null;
15725        List<BroadcastFilter> registeredReceivers = null;
15726        // Need to resolve the intent to interested receivers...
15727        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15728                 == 0) {
15729            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15730        }
15731        if (intent.getComponent() == null) {
15732            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15733                // Query one target user at a time, excluding shell-restricted users
15734                UserManagerService ums = getUserManagerLocked();
15735                for (int i = 0; i < users.length; i++) {
15736                    if (ums.hasUserRestriction(
15737                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15738                        continue;
15739                    }
15740                    List<BroadcastFilter> registeredReceiversForUser =
15741                            mReceiverResolver.queryIntent(intent,
15742                                    resolvedType, false, users[i]);
15743                    if (registeredReceivers == null) {
15744                        registeredReceivers = registeredReceiversForUser;
15745                    } else if (registeredReceiversForUser != null) {
15746                        registeredReceivers.addAll(registeredReceiversForUser);
15747                    }
15748                }
15749            } else {
15750                registeredReceivers = mReceiverResolver.queryIntent(intent,
15751                        resolvedType, false, userId);
15752            }
15753        }
15754
15755        final boolean replacePending =
15756                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15757
15758        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15759                + " replacePending=" + replacePending);
15760
15761        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15762        if (!ordered && NR > 0) {
15763            // If we are not serializing this broadcast, then send the
15764            // registered receivers separately so they don't wait for the
15765            // components to be launched.
15766            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15767            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15768                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15769                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15770                    ordered, sticky, false, userId);
15771            if (DEBUG_BROADCAST) Slog.v(
15772                    TAG, "Enqueueing parallel broadcast " + r);
15773            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15774            if (!replaced) {
15775                queue.enqueueParallelBroadcastLocked(r);
15776                queue.scheduleBroadcastsLocked();
15777            }
15778            registeredReceivers = null;
15779            NR = 0;
15780        }
15781
15782        // Merge into one list.
15783        int ir = 0;
15784        if (receivers != null) {
15785            // A special case for PACKAGE_ADDED: do not allow the package
15786            // being added to see this broadcast.  This prevents them from
15787            // using this as a back door to get run as soon as they are
15788            // installed.  Maybe in the future we want to have a special install
15789            // broadcast or such for apps, but we'd like to deliberately make
15790            // this decision.
15791            String skipPackages[] = null;
15792            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15793                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15794                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15795                Uri data = intent.getData();
15796                if (data != null) {
15797                    String pkgName = data.getSchemeSpecificPart();
15798                    if (pkgName != null) {
15799                        skipPackages = new String[] { pkgName };
15800                    }
15801                }
15802            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15803                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15804            }
15805            if (skipPackages != null && (skipPackages.length > 0)) {
15806                for (String skipPackage : skipPackages) {
15807                    if (skipPackage != null) {
15808                        int NT = receivers.size();
15809                        for (int it=0; it<NT; it++) {
15810                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15811                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15812                                receivers.remove(it);
15813                                it--;
15814                                NT--;
15815                            }
15816                        }
15817                    }
15818                }
15819            }
15820
15821            int NT = receivers != null ? receivers.size() : 0;
15822            int it = 0;
15823            ResolveInfo curt = null;
15824            BroadcastFilter curr = null;
15825            while (it < NT && ir < NR) {
15826                if (curt == null) {
15827                    curt = (ResolveInfo)receivers.get(it);
15828                }
15829                if (curr == null) {
15830                    curr = registeredReceivers.get(ir);
15831                }
15832                if (curr.getPriority() >= curt.priority) {
15833                    // Insert this broadcast record into the final list.
15834                    receivers.add(it, curr);
15835                    ir++;
15836                    curr = null;
15837                    it++;
15838                    NT++;
15839                } else {
15840                    // Skip to the next ResolveInfo in the final list.
15841                    it++;
15842                    curt = null;
15843                }
15844            }
15845        }
15846        while (ir < NR) {
15847            if (receivers == null) {
15848                receivers = new ArrayList();
15849            }
15850            receivers.add(registeredReceivers.get(ir));
15851            ir++;
15852        }
15853
15854        if ((receivers != null && receivers.size() > 0)
15855                || resultTo != null) {
15856            BroadcastQueue queue = broadcastQueueForIntent(intent);
15857            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15858                    callerPackage, callingPid, callingUid, resolvedType,
15859                    requiredPermission, appOp, receivers, resultTo, resultCode,
15860                    resultData, map, ordered, sticky, false, userId);
15861
15862            if (DEBUG_BROADCAST) Slog.v(
15863                    TAG, "Enqueueing ordered broadcast " + r
15864                    + ": prev had " + queue.mOrderedBroadcasts.size());
15865            if (DEBUG_BROADCAST) Slog.i(
15866                    TAG, "Enqueueing broadcast " + r.intent.getAction());
15867
15868            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15869            if (!replaced) {
15870                queue.enqueueOrderedBroadcastLocked(r);
15871                queue.scheduleBroadcastsLocked();
15872            }
15873        }
15874
15875        return ActivityManager.BROADCAST_SUCCESS;
15876    }
15877
15878    final Intent verifyBroadcastLocked(Intent intent) {
15879        // Refuse possible leaked file descriptors
15880        if (intent != null && intent.hasFileDescriptors() == true) {
15881            throw new IllegalArgumentException("File descriptors passed in Intent");
15882        }
15883
15884        int flags = intent.getFlags();
15885
15886        if (!mProcessesReady) {
15887            // if the caller really truly claims to know what they're doing, go
15888            // ahead and allow the broadcast without launching any receivers
15889            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15890                intent = new Intent(intent);
15891                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15892            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15893                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15894                        + " before boot completion");
15895                throw new IllegalStateException("Cannot broadcast before boot completed");
15896            }
15897        }
15898
15899        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15900            throw new IllegalArgumentException(
15901                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15902        }
15903
15904        return intent;
15905    }
15906
15907    public final int broadcastIntent(IApplicationThread caller,
15908            Intent intent, String resolvedType, IIntentReceiver resultTo,
15909            int resultCode, String resultData, Bundle map,
15910            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15911        enforceNotIsolatedCaller("broadcastIntent");
15912        synchronized(this) {
15913            intent = verifyBroadcastLocked(intent);
15914
15915            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15916            final int callingPid = Binder.getCallingPid();
15917            final int callingUid = Binder.getCallingUid();
15918            final long origId = Binder.clearCallingIdentity();
15919            int res = broadcastIntentLocked(callerApp,
15920                    callerApp != null ? callerApp.info.packageName : null,
15921                    intent, resolvedType, resultTo,
15922                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15923                    callingPid, callingUid, userId);
15924            Binder.restoreCallingIdentity(origId);
15925            return res;
15926        }
15927    }
15928
15929    int broadcastIntentInPackage(String packageName, int uid,
15930            Intent intent, String resolvedType, IIntentReceiver resultTo,
15931            int resultCode, String resultData, Bundle map,
15932            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15933        synchronized(this) {
15934            intent = verifyBroadcastLocked(intent);
15935
15936            final long origId = Binder.clearCallingIdentity();
15937            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15938                    resultTo, resultCode, resultData, map, requiredPermission,
15939                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15940            Binder.restoreCallingIdentity(origId);
15941            return res;
15942        }
15943    }
15944
15945    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15946        // Refuse possible leaked file descriptors
15947        if (intent != null && intent.hasFileDescriptors() == true) {
15948            throw new IllegalArgumentException("File descriptors passed in Intent");
15949        }
15950
15951        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15952                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15953
15954        synchronized(this) {
15955            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15956                    != PackageManager.PERMISSION_GRANTED) {
15957                String msg = "Permission Denial: unbroadcastIntent() from pid="
15958                        + Binder.getCallingPid()
15959                        + ", uid=" + Binder.getCallingUid()
15960                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15961                Slog.w(TAG, msg);
15962                throw new SecurityException(msg);
15963            }
15964            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15965            if (stickies != null) {
15966                ArrayList<Intent> list = stickies.get(intent.getAction());
15967                if (list != null) {
15968                    int N = list.size();
15969                    int i;
15970                    for (i=0; i<N; i++) {
15971                        if (intent.filterEquals(list.get(i))) {
15972                            list.remove(i);
15973                            break;
15974                        }
15975                    }
15976                    if (list.size() <= 0) {
15977                        stickies.remove(intent.getAction());
15978                    }
15979                }
15980                if (stickies.size() <= 0) {
15981                    mStickyBroadcasts.remove(userId);
15982                }
15983            }
15984        }
15985    }
15986
15987    void backgroundServicesFinishedLocked(int userId) {
15988        for (BroadcastQueue queue : mBroadcastQueues) {
15989            queue.backgroundServicesFinishedLocked(userId);
15990        }
15991    }
15992
15993    public void finishReceiver(IBinder who, int resultCode, String resultData,
15994            Bundle resultExtras, boolean resultAbort, int flags) {
15995        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15996
15997        // Refuse possible leaked file descriptors
15998        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15999            throw new IllegalArgumentException("File descriptors passed in Bundle");
16000        }
16001
16002        final long origId = Binder.clearCallingIdentity();
16003        try {
16004            boolean doNext = false;
16005            BroadcastRecord r;
16006
16007            synchronized(this) {
16008                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16009                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16010                r = queue.getMatchingOrderedReceiver(who);
16011                if (r != null) {
16012                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16013                        resultData, resultExtras, resultAbort, true);
16014                }
16015            }
16016
16017            if (doNext) {
16018                r.queue.processNextBroadcast(false);
16019            }
16020            trimApplications();
16021        } finally {
16022            Binder.restoreCallingIdentity(origId);
16023        }
16024    }
16025
16026    // =========================================================
16027    // INSTRUMENTATION
16028    // =========================================================
16029
16030    public boolean startInstrumentation(ComponentName className,
16031            String profileFile, int flags, Bundle arguments,
16032            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16033            int userId, String abiOverride) {
16034        enforceNotIsolatedCaller("startInstrumentation");
16035        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16036                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16037        // Refuse possible leaked file descriptors
16038        if (arguments != null && arguments.hasFileDescriptors()) {
16039            throw new IllegalArgumentException("File descriptors passed in Bundle");
16040        }
16041
16042        synchronized(this) {
16043            InstrumentationInfo ii = null;
16044            ApplicationInfo ai = null;
16045            try {
16046                ii = mContext.getPackageManager().getInstrumentationInfo(
16047                    className, STOCK_PM_FLAGS);
16048                ai = AppGlobals.getPackageManager().getApplicationInfo(
16049                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16050            } catch (PackageManager.NameNotFoundException e) {
16051            } catch (RemoteException e) {
16052            }
16053            if (ii == null) {
16054                reportStartInstrumentationFailure(watcher, className,
16055                        "Unable to find instrumentation info for: " + className);
16056                return false;
16057            }
16058            if (ai == null) {
16059                reportStartInstrumentationFailure(watcher, className,
16060                        "Unable to find instrumentation target package: " + ii.targetPackage);
16061                return false;
16062            }
16063
16064            int match = mContext.getPackageManager().checkSignatures(
16065                    ii.targetPackage, ii.packageName);
16066            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16067                String msg = "Permission Denial: starting instrumentation "
16068                        + className + " from pid="
16069                        + Binder.getCallingPid()
16070                        + ", uid=" + Binder.getCallingPid()
16071                        + " not allowed because package " + ii.packageName
16072                        + " does not have a signature matching the target "
16073                        + ii.targetPackage;
16074                reportStartInstrumentationFailure(watcher, className, msg);
16075                throw new SecurityException(msg);
16076            }
16077
16078            final long origId = Binder.clearCallingIdentity();
16079            // Instrumentation can kill and relaunch even persistent processes
16080            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16081                    "start instr");
16082            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16083            app.instrumentationClass = className;
16084            app.instrumentationInfo = ai;
16085            app.instrumentationProfileFile = profileFile;
16086            app.instrumentationArguments = arguments;
16087            app.instrumentationWatcher = watcher;
16088            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16089            app.instrumentationResultClass = className;
16090            Binder.restoreCallingIdentity(origId);
16091        }
16092
16093        return true;
16094    }
16095
16096    /**
16097     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16098     * error to the logs, but if somebody is watching, send the report there too.  This enables
16099     * the "am" command to report errors with more information.
16100     *
16101     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16102     * @param cn The component name of the instrumentation.
16103     * @param report The error report.
16104     */
16105    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16106            ComponentName cn, String report) {
16107        Slog.w(TAG, report);
16108        try {
16109            if (watcher != null) {
16110                Bundle results = new Bundle();
16111                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16112                results.putString("Error", report);
16113                watcher.instrumentationStatus(cn, -1, results);
16114            }
16115        } catch (RemoteException e) {
16116            Slog.w(TAG, e);
16117        }
16118    }
16119
16120    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16121        if (app.instrumentationWatcher != null) {
16122            try {
16123                // NOTE:  IInstrumentationWatcher *must* be oneway here
16124                app.instrumentationWatcher.instrumentationFinished(
16125                    app.instrumentationClass,
16126                    resultCode,
16127                    results);
16128            } catch (RemoteException e) {
16129            }
16130        }
16131        if (app.instrumentationUiAutomationConnection != null) {
16132            try {
16133                app.instrumentationUiAutomationConnection.shutdown();
16134            } catch (RemoteException re) {
16135                /* ignore */
16136            }
16137            // Only a UiAutomation can set this flag and now that
16138            // it is finished we make sure it is reset to its default.
16139            mUserIsMonkey = false;
16140        }
16141        app.instrumentationWatcher = null;
16142        app.instrumentationUiAutomationConnection = null;
16143        app.instrumentationClass = null;
16144        app.instrumentationInfo = null;
16145        app.instrumentationProfileFile = null;
16146        app.instrumentationArguments = null;
16147
16148        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16149                "finished inst");
16150    }
16151
16152    public void finishInstrumentation(IApplicationThread target,
16153            int resultCode, Bundle results) {
16154        int userId = UserHandle.getCallingUserId();
16155        // Refuse possible leaked file descriptors
16156        if (results != null && results.hasFileDescriptors()) {
16157            throw new IllegalArgumentException("File descriptors passed in Intent");
16158        }
16159
16160        synchronized(this) {
16161            ProcessRecord app = getRecordForAppLocked(target);
16162            if (app == null) {
16163                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16164                return;
16165            }
16166            final long origId = Binder.clearCallingIdentity();
16167            finishInstrumentationLocked(app, resultCode, results);
16168            Binder.restoreCallingIdentity(origId);
16169        }
16170    }
16171
16172    // =========================================================
16173    // CONFIGURATION
16174    // =========================================================
16175
16176    public ConfigurationInfo getDeviceConfigurationInfo() {
16177        ConfigurationInfo config = new ConfigurationInfo();
16178        synchronized (this) {
16179            config.reqTouchScreen = mConfiguration.touchscreen;
16180            config.reqKeyboardType = mConfiguration.keyboard;
16181            config.reqNavigation = mConfiguration.navigation;
16182            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16183                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16184                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16185            }
16186            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16187                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16188                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16189            }
16190            config.reqGlEsVersion = GL_ES_VERSION;
16191        }
16192        return config;
16193    }
16194
16195    ActivityStack getFocusedStack() {
16196        return mStackSupervisor.getFocusedStack();
16197    }
16198
16199    @Override
16200    public int getFocusedStackId() throws RemoteException {
16201        ActivityStack focusedStack = getFocusedStack();
16202        if (focusedStack != null) {
16203            return focusedStack.getStackId();
16204        }
16205        return -1;
16206    }
16207
16208    public Configuration getConfiguration() {
16209        Configuration ci;
16210        synchronized(this) {
16211            ci = new Configuration(mConfiguration);
16212            ci.userSetLocale = false;
16213        }
16214        return ci;
16215    }
16216
16217    public void updatePersistentConfiguration(Configuration values) {
16218        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16219                "updateConfiguration()");
16220        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16221                "updateConfiguration()");
16222        if (values == null) {
16223            throw new NullPointerException("Configuration must not be null");
16224        }
16225
16226        synchronized(this) {
16227            final long origId = Binder.clearCallingIdentity();
16228            updateConfigurationLocked(values, null, true, false);
16229            Binder.restoreCallingIdentity(origId);
16230        }
16231    }
16232
16233    public void updateConfiguration(Configuration values) {
16234        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16235                "updateConfiguration()");
16236
16237        synchronized(this) {
16238            if (values == null && mWindowManager != null) {
16239                // sentinel: fetch the current configuration from the window manager
16240                values = mWindowManager.computeNewConfiguration();
16241            }
16242
16243            if (mWindowManager != null) {
16244                mProcessList.applyDisplaySize(mWindowManager);
16245            }
16246
16247            final long origId = Binder.clearCallingIdentity();
16248            if (values != null) {
16249                Settings.System.clearConfiguration(values);
16250            }
16251            updateConfigurationLocked(values, null, false, false);
16252            Binder.restoreCallingIdentity(origId);
16253        }
16254    }
16255
16256    /**
16257     * Do either or both things: (1) change the current configuration, and (2)
16258     * make sure the given activity is running with the (now) current
16259     * configuration.  Returns true if the activity has been left running, or
16260     * false if <var>starting</var> is being destroyed to match the new
16261     * configuration.
16262     * @param persistent TODO
16263     */
16264    boolean updateConfigurationLocked(Configuration values,
16265            ActivityRecord starting, boolean persistent, boolean initLocale) {
16266        int changes = 0;
16267
16268        if (values != null) {
16269            Configuration newConfig = new Configuration(mConfiguration);
16270            changes = newConfig.updateFrom(values);
16271            if (changes != 0) {
16272                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16273                    Slog.i(TAG, "Updating configuration to: " + values);
16274                }
16275
16276                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16277
16278                if (!initLocale && values.locale != null && values.userSetLocale) {
16279                    final String languageTag = values.locale.toLanguageTag();
16280                    SystemProperties.set("persist.sys.locale", languageTag);
16281                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16282                            values.locale));
16283                }
16284
16285                mConfigurationSeq++;
16286                if (mConfigurationSeq <= 0) {
16287                    mConfigurationSeq = 1;
16288                }
16289                newConfig.seq = mConfigurationSeq;
16290                mConfiguration = newConfig;
16291                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16292                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16293                //mUsageStatsService.noteStartConfig(newConfig);
16294
16295                final Configuration configCopy = new Configuration(mConfiguration);
16296
16297                // TODO: If our config changes, should we auto dismiss any currently
16298                // showing dialogs?
16299                mShowDialogs = shouldShowDialogs(newConfig);
16300
16301                AttributeCache ac = AttributeCache.instance();
16302                if (ac != null) {
16303                    ac.updateConfiguration(configCopy);
16304                }
16305
16306                // Make sure all resources in our process are updated
16307                // right now, so that anyone who is going to retrieve
16308                // resource values after we return will be sure to get
16309                // the new ones.  This is especially important during
16310                // boot, where the first config change needs to guarantee
16311                // all resources have that config before following boot
16312                // code is executed.
16313                mSystemThread.applyConfigurationToResources(configCopy);
16314
16315                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16316                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16317                    msg.obj = new Configuration(configCopy);
16318                    mHandler.sendMessage(msg);
16319                }
16320
16321                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16322                    ProcessRecord app = mLruProcesses.get(i);
16323                    try {
16324                        if (app.thread != null) {
16325                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16326                                    + app.processName + " new config " + mConfiguration);
16327                            app.thread.scheduleConfigurationChanged(configCopy);
16328                        }
16329                    } catch (Exception e) {
16330                    }
16331                }
16332                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16333                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16334                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16335                        | Intent.FLAG_RECEIVER_FOREGROUND);
16336                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16337                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16338                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16339                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16340                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16341                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16342                    broadcastIntentLocked(null, null, intent,
16343                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16344                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16345                }
16346            }
16347        }
16348
16349        boolean kept = true;
16350        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16351        // mainStack is null during startup.
16352        if (mainStack != null) {
16353            if (changes != 0 && starting == null) {
16354                // If the configuration changed, and the caller is not already
16355                // in the process of starting an activity, then find the top
16356                // activity to check if its configuration needs to change.
16357                starting = mainStack.topRunningActivityLocked(null);
16358            }
16359
16360            if (starting != null) {
16361                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16362                // And we need to make sure at this point that all other activities
16363                // are made visible with the correct configuration.
16364                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16365            }
16366        }
16367
16368        if (values != null && mWindowManager != null) {
16369            mWindowManager.setNewConfiguration(mConfiguration);
16370        }
16371
16372        return kept;
16373    }
16374
16375    /**
16376     * Decide based on the configuration whether we should shouw the ANR,
16377     * crash, etc dialogs.  The idea is that if there is no affordnace to
16378     * press the on-screen buttons, we shouldn't show the dialog.
16379     *
16380     * A thought: SystemUI might also want to get told about this, the Power
16381     * dialog / global actions also might want different behaviors.
16382     */
16383    private static final boolean shouldShowDialogs(Configuration config) {
16384        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16385                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
16386                && config.navigation == Configuration.NAVIGATION_NONAV);
16387    }
16388
16389    @Override
16390    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16391        synchronized (this) {
16392            ActivityRecord srec = ActivityRecord.forToken(token);
16393            if (srec.task != null && srec.task.stack != null) {
16394                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16395            }
16396        }
16397        return false;
16398    }
16399
16400    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16401            Intent resultData) {
16402
16403        synchronized (this) {
16404            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16405            if (stack != null) {
16406                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16407            }
16408            return false;
16409        }
16410    }
16411
16412    public int getLaunchedFromUid(IBinder activityToken) {
16413        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16414        if (srec == null) {
16415            return -1;
16416        }
16417        return srec.launchedFromUid;
16418    }
16419
16420    public String getLaunchedFromPackage(IBinder activityToken) {
16421        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16422        if (srec == null) {
16423            return null;
16424        }
16425        return srec.launchedFromPackage;
16426    }
16427
16428    // =========================================================
16429    // LIFETIME MANAGEMENT
16430    // =========================================================
16431
16432    // Returns which broadcast queue the app is the current [or imminent] receiver
16433    // on, or 'null' if the app is not an active broadcast recipient.
16434    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16435        BroadcastRecord r = app.curReceiver;
16436        if (r != null) {
16437            return r.queue;
16438        }
16439
16440        // It's not the current receiver, but it might be starting up to become one
16441        synchronized (this) {
16442            for (BroadcastQueue queue : mBroadcastQueues) {
16443                r = queue.mPendingBroadcast;
16444                if (r != null && r.curApp == app) {
16445                    // found it; report which queue it's in
16446                    return queue;
16447                }
16448            }
16449        }
16450
16451        return null;
16452    }
16453
16454    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16455            ComponentName targetComponent, String targetProcess) {
16456        if (!mTrackingAssociations) {
16457            return null;
16458        }
16459        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16460                = mAssociations.get(targetUid);
16461        if (components == null) {
16462            components = new ArrayMap<>();
16463            mAssociations.put(targetUid, components);
16464        }
16465        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16466        if (sourceUids == null) {
16467            sourceUids = new SparseArray<>();
16468            components.put(targetComponent, sourceUids);
16469        }
16470        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16471        if (sourceProcesses == null) {
16472            sourceProcesses = new ArrayMap<>();
16473            sourceUids.put(sourceUid, sourceProcesses);
16474        }
16475        Association ass = sourceProcesses.get(sourceProcess);
16476        if (ass == null) {
16477            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16478                    targetProcess);
16479            sourceProcesses.put(sourceProcess, ass);
16480        }
16481        ass.mCount++;
16482        ass.mNesting++;
16483        if (ass.mNesting == 1) {
16484            ass.mStartTime = SystemClock.uptimeMillis();
16485        }
16486        return ass;
16487    }
16488
16489    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16490            ComponentName targetComponent) {
16491        if (!mTrackingAssociations) {
16492            return;
16493        }
16494        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16495                = mAssociations.get(targetUid);
16496        if (components == null) {
16497            return;
16498        }
16499        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16500        if (sourceUids == null) {
16501            return;
16502        }
16503        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16504        if (sourceProcesses == null) {
16505            return;
16506        }
16507        Association ass = sourceProcesses.get(sourceProcess);
16508        if (ass == null || ass.mNesting <= 0) {
16509            return;
16510        }
16511        ass.mNesting--;
16512        if (ass.mNesting == 0) {
16513            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16514        }
16515    }
16516
16517    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16518            boolean doingAll, long now) {
16519        if (mAdjSeq == app.adjSeq) {
16520            // This adjustment has already been computed.
16521            return app.curRawAdj;
16522        }
16523
16524        if (app.thread == null) {
16525            app.adjSeq = mAdjSeq;
16526            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16527            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16528            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16529        }
16530
16531        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16532        app.adjSource = null;
16533        app.adjTarget = null;
16534        app.empty = false;
16535        app.cached = false;
16536
16537        final int activitiesSize = app.activities.size();
16538
16539        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16540            // The max adjustment doesn't allow this app to be anything
16541            // below foreground, so it is not worth doing work for it.
16542            app.adjType = "fixed";
16543            app.adjSeq = mAdjSeq;
16544            app.curRawAdj = app.maxAdj;
16545            app.foregroundActivities = false;
16546            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16547            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16548            // System processes can do UI, and when they do we want to have
16549            // them trim their memory after the user leaves the UI.  To
16550            // facilitate this, here we need to determine whether or not it
16551            // is currently showing UI.
16552            app.systemNoUi = true;
16553            if (app == TOP_APP) {
16554                app.systemNoUi = false;
16555            } else if (activitiesSize > 0) {
16556                for (int j = 0; j < activitiesSize; j++) {
16557                    final ActivityRecord r = app.activities.get(j);
16558                    if (r.visible) {
16559                        app.systemNoUi = false;
16560                    }
16561                }
16562            }
16563            if (!app.systemNoUi) {
16564                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16565            }
16566            return (app.curAdj=app.maxAdj);
16567        }
16568
16569        app.systemNoUi = false;
16570
16571        // Determine the importance of the process, starting with most
16572        // important to least, and assign an appropriate OOM adjustment.
16573        int adj;
16574        int schedGroup;
16575        int procState;
16576        boolean foregroundActivities = false;
16577        BroadcastQueue queue;
16578        if (app == TOP_APP) {
16579            // The last app on the list is the foreground app.
16580            adj = ProcessList.FOREGROUND_APP_ADJ;
16581            schedGroup = Process.THREAD_GROUP_DEFAULT;
16582            app.adjType = "top-activity";
16583            foregroundActivities = true;
16584            procState = ActivityManager.PROCESS_STATE_TOP;
16585        } else if (app.instrumentationClass != null) {
16586            // Don't want to kill running instrumentation.
16587            adj = ProcessList.FOREGROUND_APP_ADJ;
16588            schedGroup = Process.THREAD_GROUP_DEFAULT;
16589            app.adjType = "instrumentation";
16590            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16591        } else if ((queue = isReceivingBroadcast(app)) != null) {
16592            // An app that is currently receiving a broadcast also
16593            // counts as being in the foreground for OOM killer purposes.
16594            // It's placed in a sched group based on the nature of the
16595            // broadcast as reflected by which queue it's active in.
16596            adj = ProcessList.FOREGROUND_APP_ADJ;
16597            schedGroup = (queue == mFgBroadcastQueue)
16598                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16599            app.adjType = "broadcast";
16600            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16601        } else if (app.executingServices.size() > 0) {
16602            // An app that is currently executing a service callback also
16603            // counts as being in the foreground.
16604            adj = ProcessList.FOREGROUND_APP_ADJ;
16605            schedGroup = app.execServicesFg ?
16606                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16607            app.adjType = "exec-service";
16608            procState = ActivityManager.PROCESS_STATE_SERVICE;
16609            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16610        } else {
16611            // As far as we know the process is empty.  We may change our mind later.
16612            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16613            // At this point we don't actually know the adjustment.  Use the cached adj
16614            // value that the caller wants us to.
16615            adj = cachedAdj;
16616            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16617            app.cached = true;
16618            app.empty = true;
16619            app.adjType = "cch-empty";
16620        }
16621
16622        // Examine all activities if not already foreground.
16623        if (!foregroundActivities && activitiesSize > 0) {
16624            for (int j = 0; j < activitiesSize; j++) {
16625                final ActivityRecord r = app.activities.get(j);
16626                if (r.app != app) {
16627                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16628                            + app + "?!?");
16629                    continue;
16630                }
16631                if (r.visible) {
16632                    // App has a visible activity; only upgrade adjustment.
16633                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16634                        adj = ProcessList.VISIBLE_APP_ADJ;
16635                        app.adjType = "visible";
16636                    }
16637                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16638                        procState = ActivityManager.PROCESS_STATE_TOP;
16639                    }
16640                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16641                    app.cached = false;
16642                    app.empty = false;
16643                    foregroundActivities = true;
16644                    break;
16645                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16646                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16647                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16648                        app.adjType = "pausing";
16649                    }
16650                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16651                        procState = ActivityManager.PROCESS_STATE_TOP;
16652                    }
16653                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16654                    app.cached = false;
16655                    app.empty = false;
16656                    foregroundActivities = true;
16657                } else if (r.state == ActivityState.STOPPING) {
16658                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16659                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16660                        app.adjType = "stopping";
16661                    }
16662                    // For the process state, we will at this point consider the
16663                    // process to be cached.  It will be cached either as an activity
16664                    // or empty depending on whether the activity is finishing.  We do
16665                    // this so that we can treat the process as cached for purposes of
16666                    // memory trimming (determing current memory level, trim command to
16667                    // send to process) since there can be an arbitrary number of stopping
16668                    // processes and they should soon all go into the cached state.
16669                    if (!r.finishing) {
16670                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16671                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16672                        }
16673                    }
16674                    app.cached = false;
16675                    app.empty = false;
16676                    foregroundActivities = true;
16677                } else {
16678                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16679                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16680                        app.adjType = "cch-act";
16681                    }
16682                }
16683            }
16684        }
16685
16686        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16687            if (app.foregroundServices) {
16688                // The user is aware of this app, so make it visible.
16689                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16690                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16691                app.cached = false;
16692                app.adjType = "fg-service";
16693                schedGroup = Process.THREAD_GROUP_DEFAULT;
16694            } else if (app.forcingToForeground != null) {
16695                // The user is aware of this app, so make it visible.
16696                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16697                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16698                app.cached = false;
16699                app.adjType = "force-fg";
16700                app.adjSource = app.forcingToForeground;
16701                schedGroup = Process.THREAD_GROUP_DEFAULT;
16702            }
16703        }
16704
16705        if (app == mHeavyWeightProcess) {
16706            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16707                // We don't want to kill the current heavy-weight process.
16708                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16709                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16710                app.cached = false;
16711                app.adjType = "heavy";
16712            }
16713            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16714                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16715            }
16716        }
16717
16718        if (app == mHomeProcess) {
16719            if (adj > ProcessList.HOME_APP_ADJ) {
16720                // This process is hosting what we currently consider to be the
16721                // home app, so we don't want to let it go into the background.
16722                adj = ProcessList.HOME_APP_ADJ;
16723                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16724                app.cached = false;
16725                app.adjType = "home";
16726            }
16727            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16728                procState = ActivityManager.PROCESS_STATE_HOME;
16729            }
16730        }
16731
16732        if (app == mPreviousProcess && app.activities.size() > 0) {
16733            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16734                // This was the previous process that showed UI to the user.
16735                // We want to try to keep it around more aggressively, to give
16736                // a good experience around switching between two apps.
16737                adj = ProcessList.PREVIOUS_APP_ADJ;
16738                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16739                app.cached = false;
16740                app.adjType = "previous";
16741            }
16742            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16743                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16744            }
16745        }
16746
16747        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16748                + " reason=" + app.adjType);
16749
16750        // By default, we use the computed adjustment.  It may be changed if
16751        // there are applications dependent on our services or providers, but
16752        // this gives us a baseline and makes sure we don't get into an
16753        // infinite recursion.
16754        app.adjSeq = mAdjSeq;
16755        app.curRawAdj = adj;
16756        app.hasStartedServices = false;
16757
16758        if (mBackupTarget != null && app == mBackupTarget.app) {
16759            // If possible we want to avoid killing apps while they're being backed up
16760            if (adj > ProcessList.BACKUP_APP_ADJ) {
16761                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16762                adj = ProcessList.BACKUP_APP_ADJ;
16763                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16764                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16765                }
16766                app.adjType = "backup";
16767                app.cached = false;
16768            }
16769            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16770                procState = ActivityManager.PROCESS_STATE_BACKUP;
16771            }
16772        }
16773
16774        boolean mayBeTop = false;
16775
16776        for (int is = app.services.size()-1;
16777                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16778                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16779                        || procState > ActivityManager.PROCESS_STATE_TOP);
16780                is--) {
16781            ServiceRecord s = app.services.valueAt(is);
16782            if (s.startRequested) {
16783                app.hasStartedServices = true;
16784                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16785                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16786                }
16787                if (app.hasShownUi && app != mHomeProcess) {
16788                    // If this process has shown some UI, let it immediately
16789                    // go to the LRU list because it may be pretty heavy with
16790                    // UI stuff.  We'll tag it with a label just to help
16791                    // debug and understand what is going on.
16792                    if (adj > ProcessList.SERVICE_ADJ) {
16793                        app.adjType = "cch-started-ui-services";
16794                    }
16795                } else {
16796                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16797                        // This service has seen some activity within
16798                        // recent memory, so we will keep its process ahead
16799                        // of the background processes.
16800                        if (adj > ProcessList.SERVICE_ADJ) {
16801                            adj = ProcessList.SERVICE_ADJ;
16802                            app.adjType = "started-services";
16803                            app.cached = false;
16804                        }
16805                    }
16806                    // If we have let the service slide into the background
16807                    // state, still have some text describing what it is doing
16808                    // even though the service no longer has an impact.
16809                    if (adj > ProcessList.SERVICE_ADJ) {
16810                        app.adjType = "cch-started-services";
16811                    }
16812                }
16813            }
16814            for (int conni = s.connections.size()-1;
16815                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16816                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16817                            || procState > ActivityManager.PROCESS_STATE_TOP);
16818                    conni--) {
16819                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16820                for (int i = 0;
16821                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16822                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16823                                || procState > ActivityManager.PROCESS_STATE_TOP);
16824                        i++) {
16825                    // XXX should compute this based on the max of
16826                    // all connected clients.
16827                    ConnectionRecord cr = clist.get(i);
16828                    if (cr.binding.client == app) {
16829                        // Binding to ourself is not interesting.
16830                        continue;
16831                    }
16832                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16833                        ProcessRecord client = cr.binding.client;
16834                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16835                                TOP_APP, doingAll, now);
16836                        int clientProcState = client.curProcState;
16837                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16838                            // If the other app is cached for any reason, for purposes here
16839                            // we are going to consider it empty.  The specific cached state
16840                            // doesn't propagate except under certain conditions.
16841                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16842                        }
16843                        String adjType = null;
16844                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16845                            // Not doing bind OOM management, so treat
16846                            // this guy more like a started service.
16847                            if (app.hasShownUi && app != mHomeProcess) {
16848                                // If this process has shown some UI, let it immediately
16849                                // go to the LRU list because it may be pretty heavy with
16850                                // UI stuff.  We'll tag it with a label just to help
16851                                // debug and understand what is going on.
16852                                if (adj > clientAdj) {
16853                                    adjType = "cch-bound-ui-services";
16854                                }
16855                                app.cached = false;
16856                                clientAdj = adj;
16857                                clientProcState = procState;
16858                            } else {
16859                                if (now >= (s.lastActivity
16860                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16861                                    // This service has not seen activity within
16862                                    // recent memory, so allow it to drop to the
16863                                    // LRU list if there is no other reason to keep
16864                                    // it around.  We'll also tag it with a label just
16865                                    // to help debug and undertand what is going on.
16866                                    if (adj > clientAdj) {
16867                                        adjType = "cch-bound-services";
16868                                    }
16869                                    clientAdj = adj;
16870                                }
16871                            }
16872                        }
16873                        if (adj > clientAdj) {
16874                            // If this process has recently shown UI, and
16875                            // the process that is binding to it is less
16876                            // important than being visible, then we don't
16877                            // care about the binding as much as we care
16878                            // about letting this process get into the LRU
16879                            // list to be killed and restarted if needed for
16880                            // memory.
16881                            if (app.hasShownUi && app != mHomeProcess
16882                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16883                                adjType = "cch-bound-ui-services";
16884                            } else {
16885                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16886                                        |Context.BIND_IMPORTANT)) != 0) {
16887                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16888                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16889                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16890                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16891                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16892                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16893                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16894                                    adj = clientAdj;
16895                                } else {
16896                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16897                                        adj = ProcessList.VISIBLE_APP_ADJ;
16898                                    }
16899                                }
16900                                if (!client.cached) {
16901                                    app.cached = false;
16902                                }
16903                                adjType = "service";
16904                            }
16905                        }
16906                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16907                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16908                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16909                            }
16910                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16911                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16912                                    // Special handling of clients who are in the top state.
16913                                    // We *may* want to consider this process to be in the
16914                                    // top state as well, but only if there is not another
16915                                    // reason for it to be running.  Being on the top is a
16916                                    // special state, meaning you are specifically running
16917                                    // for the current top app.  If the process is already
16918                                    // running in the background for some other reason, it
16919                                    // is more important to continue considering it to be
16920                                    // in the background state.
16921                                    mayBeTop = true;
16922                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16923                                } else {
16924                                    // Special handling for above-top states (persistent
16925                                    // processes).  These should not bring the current process
16926                                    // into the top state, since they are not on top.  Instead
16927                                    // give them the best state after that.
16928                                    clientProcState =
16929                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16930                                }
16931                            }
16932                        } else {
16933                            if (clientProcState <
16934                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16935                                clientProcState =
16936                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16937                            }
16938                        }
16939                        if (procState > clientProcState) {
16940                            procState = clientProcState;
16941                        }
16942                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16943                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16944                            app.pendingUiClean = true;
16945                        }
16946                        if (adjType != null) {
16947                            app.adjType = adjType;
16948                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16949                                    .REASON_SERVICE_IN_USE;
16950                            app.adjSource = cr.binding.client;
16951                            app.adjSourceProcState = clientProcState;
16952                            app.adjTarget = s.name;
16953                        }
16954                    }
16955                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16956                        app.treatLikeActivity = true;
16957                    }
16958                    final ActivityRecord a = cr.activity;
16959                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16960                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16961                                (a.visible || a.state == ActivityState.RESUMED
16962                                 || a.state == ActivityState.PAUSING)) {
16963                            adj = ProcessList.FOREGROUND_APP_ADJ;
16964                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16965                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16966                            }
16967                            app.cached = false;
16968                            app.adjType = "service";
16969                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16970                                    .REASON_SERVICE_IN_USE;
16971                            app.adjSource = a;
16972                            app.adjSourceProcState = procState;
16973                            app.adjTarget = s.name;
16974                        }
16975                    }
16976                }
16977            }
16978        }
16979
16980        for (int provi = app.pubProviders.size()-1;
16981                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16982                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16983                        || procState > ActivityManager.PROCESS_STATE_TOP);
16984                provi--) {
16985            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16986            for (int i = cpr.connections.size()-1;
16987                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16988                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16989                            || procState > ActivityManager.PROCESS_STATE_TOP);
16990                    i--) {
16991                ContentProviderConnection conn = cpr.connections.get(i);
16992                ProcessRecord client = conn.client;
16993                if (client == app) {
16994                    // Being our own client is not interesting.
16995                    continue;
16996                }
16997                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16998                int clientProcState = client.curProcState;
16999                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17000                    // If the other app is cached for any reason, for purposes here
17001                    // we are going to consider it empty.
17002                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17003                }
17004                if (adj > clientAdj) {
17005                    if (app.hasShownUi && app != mHomeProcess
17006                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17007                        app.adjType = "cch-ui-provider";
17008                    } else {
17009                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17010                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17011                        app.adjType = "provider";
17012                    }
17013                    app.cached &= client.cached;
17014                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17015                            .REASON_PROVIDER_IN_USE;
17016                    app.adjSource = client;
17017                    app.adjSourceProcState = clientProcState;
17018                    app.adjTarget = cpr.name;
17019                }
17020                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17021                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17022                        // Special handling of clients who are in the top state.
17023                        // We *may* want to consider this process to be in the
17024                        // top state as well, but only if there is not another
17025                        // reason for it to be running.  Being on the top is a
17026                        // special state, meaning you are specifically running
17027                        // for the current top app.  If the process is already
17028                        // running in the background for some other reason, it
17029                        // is more important to continue considering it to be
17030                        // in the background state.
17031                        mayBeTop = true;
17032                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17033                    } else {
17034                        // Special handling for above-top states (persistent
17035                        // processes).  These should not bring the current process
17036                        // into the top state, since they are not on top.  Instead
17037                        // give them the best state after that.
17038                        clientProcState =
17039                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17040                    }
17041                }
17042                if (procState > clientProcState) {
17043                    procState = clientProcState;
17044                }
17045                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17046                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17047                }
17048            }
17049            // If the provider has external (non-framework) process
17050            // dependencies, ensure that its adjustment is at least
17051            // FOREGROUND_APP_ADJ.
17052            if (cpr.hasExternalProcessHandles()) {
17053                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17054                    adj = ProcessList.FOREGROUND_APP_ADJ;
17055                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17056                    app.cached = false;
17057                    app.adjType = "provider";
17058                    app.adjTarget = cpr.name;
17059                }
17060                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17061                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17062                }
17063            }
17064        }
17065
17066        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17067            // A client of one of our services or providers is in the top state.  We
17068            // *may* want to be in the top state, but not if we are already running in
17069            // the background for some other reason.  For the decision here, we are going
17070            // to pick out a few specific states that we want to remain in when a client
17071            // is top (states that tend to be longer-term) and otherwise allow it to go
17072            // to the top state.
17073            switch (procState) {
17074                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17075                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17076                case ActivityManager.PROCESS_STATE_SERVICE:
17077                    // These all are longer-term states, so pull them up to the top
17078                    // of the background states, but not all the way to the top state.
17079                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17080                    break;
17081                default:
17082                    // Otherwise, top is a better choice, so take it.
17083                    procState = ActivityManager.PROCESS_STATE_TOP;
17084                    break;
17085            }
17086        }
17087
17088        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17089            if (app.hasClientActivities) {
17090                // This is a cached process, but with client activities.  Mark it so.
17091                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17092                app.adjType = "cch-client-act";
17093            } else if (app.treatLikeActivity) {
17094                // This is a cached process, but somebody wants us to treat it like it has
17095                // an activity, okay!
17096                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17097                app.adjType = "cch-as-act";
17098            }
17099        }
17100
17101        if (adj == ProcessList.SERVICE_ADJ) {
17102            if (doingAll) {
17103                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17104                mNewNumServiceProcs++;
17105                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17106                if (!app.serviceb) {
17107                    // This service isn't far enough down on the LRU list to
17108                    // normally be a B service, but if we are low on RAM and it
17109                    // is large we want to force it down since we would prefer to
17110                    // keep launcher over it.
17111                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17112                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17113                        app.serviceHighRam = true;
17114                        app.serviceb = true;
17115                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17116                    } else {
17117                        mNewNumAServiceProcs++;
17118                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17119                    }
17120                } else {
17121                    app.serviceHighRam = false;
17122                }
17123            }
17124            if (app.serviceb) {
17125                adj = ProcessList.SERVICE_B_ADJ;
17126            }
17127        }
17128
17129        app.curRawAdj = adj;
17130
17131        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17132        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17133        if (adj > app.maxAdj) {
17134            adj = app.maxAdj;
17135            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17136                schedGroup = Process.THREAD_GROUP_DEFAULT;
17137            }
17138        }
17139
17140        // Do final modification to adj.  Everything we do between here and applying
17141        // the final setAdj must be done in this function, because we will also use
17142        // it when computing the final cached adj later.  Note that we don't need to
17143        // worry about this for max adj above, since max adj will always be used to
17144        // keep it out of the cached vaues.
17145        app.curAdj = app.modifyRawOomAdj(adj);
17146        app.curSchedGroup = schedGroup;
17147        app.curProcState = procState;
17148        app.foregroundActivities = foregroundActivities;
17149
17150        return app.curRawAdj;
17151    }
17152
17153    /**
17154     * Record new PSS sample for a process.
17155     */
17156    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17157        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss*1024, uss*1024);
17158        proc.lastPssTime = now;
17159        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17160        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17161                + ": " + pss + " lastPss=" + proc.lastPss
17162                + " state=" + ProcessList.makeProcStateString(procState));
17163        if (proc.initialIdlePss == 0) {
17164            proc.initialIdlePss = pss;
17165        }
17166        proc.lastPss = pss;
17167        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17168            proc.lastCachedPss = pss;
17169        }
17170    }
17171
17172    /**
17173     * Schedule PSS collection of a process.
17174     */
17175    void requestPssLocked(ProcessRecord proc, int procState) {
17176        if (mPendingPssProcesses.contains(proc)) {
17177            return;
17178        }
17179        if (mPendingPssProcesses.size() == 0) {
17180            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17181        }
17182        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17183        proc.pssProcState = procState;
17184        mPendingPssProcesses.add(proc);
17185    }
17186
17187    /**
17188     * Schedule PSS collection of all processes.
17189     */
17190    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17191        if (!always) {
17192            if (now < (mLastFullPssTime +
17193                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17194                return;
17195            }
17196        }
17197        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17198        mLastFullPssTime = now;
17199        mFullPssPending = true;
17200        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17201        mPendingPssProcesses.clear();
17202        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17203            ProcessRecord app = mLruProcesses.get(i);
17204            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17205                app.pssProcState = app.setProcState;
17206                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17207                        mTestPssMode, isSleeping(), now);
17208                mPendingPssProcesses.add(app);
17209            }
17210        }
17211        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17212    }
17213
17214    public void setTestPssMode(boolean enabled) {
17215        synchronized (this) {
17216            mTestPssMode = enabled;
17217            if (enabled) {
17218                // Whenever we enable the mode, we want to take a snapshot all of current
17219                // process mem use.
17220                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17221            }
17222        }
17223    }
17224
17225    /**
17226     * Ask a given process to GC right now.
17227     */
17228    final void performAppGcLocked(ProcessRecord app) {
17229        try {
17230            app.lastRequestedGc = SystemClock.uptimeMillis();
17231            if (app.thread != null) {
17232                if (app.reportLowMemory) {
17233                    app.reportLowMemory = false;
17234                    app.thread.scheduleLowMemory();
17235                } else {
17236                    app.thread.processInBackground();
17237                }
17238            }
17239        } catch (Exception e) {
17240            // whatever.
17241        }
17242    }
17243
17244    /**
17245     * Returns true if things are idle enough to perform GCs.
17246     */
17247    private final boolean canGcNowLocked() {
17248        boolean processingBroadcasts = false;
17249        for (BroadcastQueue q : mBroadcastQueues) {
17250            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17251                processingBroadcasts = true;
17252            }
17253        }
17254        return !processingBroadcasts
17255                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17256    }
17257
17258    /**
17259     * Perform GCs on all processes that are waiting for it, but only
17260     * if things are idle.
17261     */
17262    final void performAppGcsLocked() {
17263        final int N = mProcessesToGc.size();
17264        if (N <= 0) {
17265            return;
17266        }
17267        if (canGcNowLocked()) {
17268            while (mProcessesToGc.size() > 0) {
17269                ProcessRecord proc = mProcessesToGc.remove(0);
17270                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17271                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17272                            <= SystemClock.uptimeMillis()) {
17273                        // To avoid spamming the system, we will GC processes one
17274                        // at a time, waiting a few seconds between each.
17275                        performAppGcLocked(proc);
17276                        scheduleAppGcsLocked();
17277                        return;
17278                    } else {
17279                        // It hasn't been long enough since we last GCed this
17280                        // process...  put it in the list to wait for its time.
17281                        addProcessToGcListLocked(proc);
17282                        break;
17283                    }
17284                }
17285            }
17286
17287            scheduleAppGcsLocked();
17288        }
17289    }
17290
17291    /**
17292     * If all looks good, perform GCs on all processes waiting for them.
17293     */
17294    final void performAppGcsIfAppropriateLocked() {
17295        if (canGcNowLocked()) {
17296            performAppGcsLocked();
17297            return;
17298        }
17299        // Still not idle, wait some more.
17300        scheduleAppGcsLocked();
17301    }
17302
17303    /**
17304     * Schedule the execution of all pending app GCs.
17305     */
17306    final void scheduleAppGcsLocked() {
17307        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17308
17309        if (mProcessesToGc.size() > 0) {
17310            // Schedule a GC for the time to the next process.
17311            ProcessRecord proc = mProcessesToGc.get(0);
17312            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17313
17314            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17315            long now = SystemClock.uptimeMillis();
17316            if (when < (now+GC_TIMEOUT)) {
17317                when = now + GC_TIMEOUT;
17318            }
17319            mHandler.sendMessageAtTime(msg, when);
17320        }
17321    }
17322
17323    /**
17324     * Add a process to the array of processes waiting to be GCed.  Keeps the
17325     * list in sorted order by the last GC time.  The process can't already be
17326     * on the list.
17327     */
17328    final void addProcessToGcListLocked(ProcessRecord proc) {
17329        boolean added = false;
17330        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17331            if (mProcessesToGc.get(i).lastRequestedGc <
17332                    proc.lastRequestedGc) {
17333                added = true;
17334                mProcessesToGc.add(i+1, proc);
17335                break;
17336            }
17337        }
17338        if (!added) {
17339            mProcessesToGc.add(0, proc);
17340        }
17341    }
17342
17343    /**
17344     * Set up to ask a process to GC itself.  This will either do it
17345     * immediately, or put it on the list of processes to gc the next
17346     * time things are idle.
17347     */
17348    final void scheduleAppGcLocked(ProcessRecord app) {
17349        long now = SystemClock.uptimeMillis();
17350        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17351            return;
17352        }
17353        if (!mProcessesToGc.contains(app)) {
17354            addProcessToGcListLocked(app);
17355            scheduleAppGcsLocked();
17356        }
17357    }
17358
17359    final void checkExcessivePowerUsageLocked(boolean doKills) {
17360        updateCpuStatsNow();
17361
17362        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17363        boolean doWakeKills = doKills;
17364        boolean doCpuKills = doKills;
17365        if (mLastPowerCheckRealtime == 0) {
17366            doWakeKills = false;
17367        }
17368        if (mLastPowerCheckUptime == 0) {
17369            doCpuKills = false;
17370        }
17371        if (stats.isScreenOn()) {
17372            doWakeKills = false;
17373        }
17374        final long curRealtime = SystemClock.elapsedRealtime();
17375        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17376        final long curUptime = SystemClock.uptimeMillis();
17377        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17378        mLastPowerCheckRealtime = curRealtime;
17379        mLastPowerCheckUptime = curUptime;
17380        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17381            doWakeKills = false;
17382        }
17383        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17384            doCpuKills = false;
17385        }
17386        int i = mLruProcesses.size();
17387        while (i > 0) {
17388            i--;
17389            ProcessRecord app = mLruProcesses.get(i);
17390            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17391                long wtime;
17392                synchronized (stats) {
17393                    wtime = stats.getProcessWakeTime(app.info.uid,
17394                            app.pid, curRealtime);
17395                }
17396                long wtimeUsed = wtime - app.lastWakeTime;
17397                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17398                if (DEBUG_POWER) {
17399                    StringBuilder sb = new StringBuilder(128);
17400                    sb.append("Wake for ");
17401                    app.toShortString(sb);
17402                    sb.append(": over ");
17403                    TimeUtils.formatDuration(realtimeSince, sb);
17404                    sb.append(" used ");
17405                    TimeUtils.formatDuration(wtimeUsed, sb);
17406                    sb.append(" (");
17407                    sb.append((wtimeUsed*100)/realtimeSince);
17408                    sb.append("%)");
17409                    Slog.i(TAG, sb.toString());
17410                    sb.setLength(0);
17411                    sb.append("CPU for ");
17412                    app.toShortString(sb);
17413                    sb.append(": over ");
17414                    TimeUtils.formatDuration(uptimeSince, sb);
17415                    sb.append(" used ");
17416                    TimeUtils.formatDuration(cputimeUsed, sb);
17417                    sb.append(" (");
17418                    sb.append((cputimeUsed*100)/uptimeSince);
17419                    sb.append("%)");
17420                    Slog.i(TAG, sb.toString());
17421                }
17422                // If a process has held a wake lock for more
17423                // than 50% of the time during this period,
17424                // that sounds bad.  Kill!
17425                if (doWakeKills && realtimeSince > 0
17426                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17427                    synchronized (stats) {
17428                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17429                                realtimeSince, wtimeUsed);
17430                    }
17431                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17432                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17433                } else if (doCpuKills && uptimeSince > 0
17434                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17435                    synchronized (stats) {
17436                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17437                                uptimeSince, cputimeUsed);
17438                    }
17439                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17440                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17441                } else {
17442                    app.lastWakeTime = wtime;
17443                    app.lastCpuTime = app.curCpuTime;
17444                }
17445            }
17446        }
17447    }
17448
17449    private final boolean applyOomAdjLocked(ProcessRecord app,
17450            ProcessRecord TOP_APP, boolean doingAll, long now) {
17451        boolean success = true;
17452
17453        if (app.curRawAdj != app.setRawAdj) {
17454            app.setRawAdj = app.curRawAdj;
17455        }
17456
17457        int changes = 0;
17458
17459        if (app.curAdj != app.setAdj) {
17460            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17461            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17462                TAG, "Set " + app.pid + " " + app.processName +
17463                " adj " + app.curAdj + ": " + app.adjType);
17464            app.setAdj = app.curAdj;
17465        }
17466
17467        if (app.setSchedGroup != app.curSchedGroup) {
17468            app.setSchedGroup = app.curSchedGroup;
17469            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17470                    "Setting process group of " + app.processName
17471                    + " to " + app.curSchedGroup);
17472            if (app.waitingToKill != null &&
17473                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17474                app.kill(app.waitingToKill, true);
17475                success = false;
17476            } else {
17477                if (true) {
17478                    long oldId = Binder.clearCallingIdentity();
17479                    try {
17480                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17481                    } catch (Exception e) {
17482                        Slog.w(TAG, "Failed setting process group of " + app.pid
17483                                + " to " + app.curSchedGroup);
17484                        e.printStackTrace();
17485                    } finally {
17486                        Binder.restoreCallingIdentity(oldId);
17487                    }
17488                } else {
17489                    if (app.thread != null) {
17490                        try {
17491                            app.thread.setSchedulingGroup(app.curSchedGroup);
17492                        } catch (RemoteException e) {
17493                        }
17494                    }
17495                }
17496                Process.setSwappiness(app.pid,
17497                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17498            }
17499        }
17500        if (app.repForegroundActivities != app.foregroundActivities) {
17501            app.repForegroundActivities = app.foregroundActivities;
17502            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17503        }
17504        if (app.repProcState != app.curProcState) {
17505            app.repProcState = app.curProcState;
17506            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17507            if (app.thread != null) {
17508                try {
17509                    if (false) {
17510                        //RuntimeException h = new RuntimeException("here");
17511                        Slog.i(TAG, "Sending new process state " + app.repProcState
17512                                + " to " + app /*, h*/);
17513                    }
17514                    app.thread.setProcessState(app.repProcState);
17515                } catch (RemoteException e) {
17516                }
17517            }
17518        }
17519        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17520                app.setProcState)) {
17521            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17522                // Experimental code to more aggressively collect pss while
17523                // running test...  the problem is that this tends to collect
17524                // the data right when a process is transitioning between process
17525                // states, which well tend to give noisy data.
17526                long start = SystemClock.uptimeMillis();
17527                long pss = Debug.getPss(app.pid, mTmpLong, null);
17528                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17529                mPendingPssProcesses.remove(app);
17530                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17531                        + " to " + app.curProcState + ": "
17532                        + (SystemClock.uptimeMillis()-start) + "ms");
17533            }
17534            app.lastStateTime = now;
17535            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17536                    mTestPssMode, isSleeping(), now);
17537            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17538                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17539                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17540                    + (app.nextPssTime-now) + ": " + app);
17541        } else {
17542            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17543                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17544                    mTestPssMode)))) {
17545                requestPssLocked(app, app.setProcState);
17546                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17547                        mTestPssMode, isSleeping(), now);
17548            } else if (false && DEBUG_PSS) {
17549                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17550            }
17551        }
17552        if (app.setProcState != app.curProcState) {
17553            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17554                    "Proc state change of " + app.processName
17555                    + " to " + app.curProcState);
17556            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17557            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17558            if (setImportant && !curImportant) {
17559                // This app is no longer something we consider important enough to allow to
17560                // use arbitrary amounts of battery power.  Note
17561                // its current wake lock time to later know to kill it if
17562                // it is not behaving well.
17563                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17564                synchronized (stats) {
17565                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17566                            app.pid, SystemClock.elapsedRealtime());
17567                }
17568                app.lastCpuTime = app.curCpuTime;
17569
17570            }
17571            app.setProcState = app.curProcState;
17572            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17573                app.notCachedSinceIdle = false;
17574            }
17575            if (!doingAll) {
17576                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17577            } else {
17578                app.procStateChanged = true;
17579            }
17580        }
17581
17582        if (changes != 0) {
17583            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17584            int i = mPendingProcessChanges.size()-1;
17585            ProcessChangeItem item = null;
17586            while (i >= 0) {
17587                item = mPendingProcessChanges.get(i);
17588                if (item.pid == app.pid) {
17589                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17590                    break;
17591                }
17592                i--;
17593            }
17594            if (i < 0) {
17595                // No existing item in pending changes; need a new one.
17596                final int NA = mAvailProcessChanges.size();
17597                if (NA > 0) {
17598                    item = mAvailProcessChanges.remove(NA-1);
17599                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17600                } else {
17601                    item = new ProcessChangeItem();
17602                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17603                }
17604                item.changes = 0;
17605                item.pid = app.pid;
17606                item.uid = app.info.uid;
17607                if (mPendingProcessChanges.size() == 0) {
17608                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17609                            "*** Enqueueing dispatch processes changed!");
17610                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17611                }
17612                mPendingProcessChanges.add(item);
17613            }
17614            item.changes |= changes;
17615            item.processState = app.repProcState;
17616            item.foregroundActivities = app.repForegroundActivities;
17617            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17618                    + Integer.toHexString(System.identityHashCode(item))
17619                    + " " + app.toShortString() + ": changes=" + item.changes
17620                    + " procState=" + item.processState
17621                    + " foreground=" + item.foregroundActivities
17622                    + " type=" + app.adjType + " source=" + app.adjSource
17623                    + " target=" + app.adjTarget);
17624        }
17625
17626        return success;
17627    }
17628
17629    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17630        if (proc.thread != null) {
17631            if (proc.baseProcessTracker != null) {
17632                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17633            }
17634            if (proc.repProcState >= 0) {
17635                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17636                        proc.repProcState);
17637            }
17638        }
17639    }
17640
17641    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17642            ProcessRecord TOP_APP, boolean doingAll, long now) {
17643        if (app.thread == null) {
17644            return false;
17645        }
17646
17647        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17648
17649        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17650    }
17651
17652    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17653            boolean oomAdj) {
17654        if (isForeground != proc.foregroundServices) {
17655            proc.foregroundServices = isForeground;
17656            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17657                    proc.info.uid);
17658            if (isForeground) {
17659                if (curProcs == null) {
17660                    curProcs = new ArrayList<ProcessRecord>();
17661                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17662                }
17663                if (!curProcs.contains(proc)) {
17664                    curProcs.add(proc);
17665                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17666                            proc.info.packageName, proc.info.uid);
17667                }
17668            } else {
17669                if (curProcs != null) {
17670                    if (curProcs.remove(proc)) {
17671                        mBatteryStatsService.noteEvent(
17672                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17673                                proc.info.packageName, proc.info.uid);
17674                        if (curProcs.size() <= 0) {
17675                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17676                        }
17677                    }
17678                }
17679            }
17680            if (oomAdj) {
17681                updateOomAdjLocked();
17682            }
17683        }
17684    }
17685
17686    private final ActivityRecord resumedAppLocked() {
17687        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17688        String pkg;
17689        int uid;
17690        if (act != null) {
17691            pkg = act.packageName;
17692            uid = act.info.applicationInfo.uid;
17693        } else {
17694            pkg = null;
17695            uid = -1;
17696        }
17697        // Has the UID or resumed package name changed?
17698        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17699                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17700            if (mCurResumedPackage != null) {
17701                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17702                        mCurResumedPackage, mCurResumedUid);
17703            }
17704            mCurResumedPackage = pkg;
17705            mCurResumedUid = uid;
17706            if (mCurResumedPackage != null) {
17707                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17708                        mCurResumedPackage, mCurResumedUid);
17709            }
17710        }
17711        return act;
17712    }
17713
17714    final boolean updateOomAdjLocked(ProcessRecord app) {
17715        final ActivityRecord TOP_ACT = resumedAppLocked();
17716        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17717        final boolean wasCached = app.cached;
17718
17719        mAdjSeq++;
17720
17721        // This is the desired cached adjusment we want to tell it to use.
17722        // If our app is currently cached, we know it, and that is it.  Otherwise,
17723        // we don't know it yet, and it needs to now be cached we will then
17724        // need to do a complete oom adj.
17725        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17726                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17727        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17728                SystemClock.uptimeMillis());
17729        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17730            // Changed to/from cached state, so apps after it in the LRU
17731            // list may also be changed.
17732            updateOomAdjLocked();
17733        }
17734        return success;
17735    }
17736
17737    final void updateOomAdjLocked() {
17738        final ActivityRecord TOP_ACT = resumedAppLocked();
17739        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17740        final long now = SystemClock.uptimeMillis();
17741        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17742        final int N = mLruProcesses.size();
17743
17744        if (false) {
17745            RuntimeException e = new RuntimeException();
17746            e.fillInStackTrace();
17747            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17748        }
17749
17750        mAdjSeq++;
17751        mNewNumServiceProcs = 0;
17752        mNewNumAServiceProcs = 0;
17753
17754        final int emptyProcessLimit;
17755        final int cachedProcessLimit;
17756        if (mProcessLimit <= 0) {
17757            emptyProcessLimit = cachedProcessLimit = 0;
17758        } else if (mProcessLimit == 1) {
17759            emptyProcessLimit = 1;
17760            cachedProcessLimit = 0;
17761        } else {
17762            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17763            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17764        }
17765
17766        // Let's determine how many processes we have running vs.
17767        // how many slots we have for background processes; we may want
17768        // to put multiple processes in a slot of there are enough of
17769        // them.
17770        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17771                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17772        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17773        if (numEmptyProcs > cachedProcessLimit) {
17774            // If there are more empty processes than our limit on cached
17775            // processes, then use the cached process limit for the factor.
17776            // This ensures that the really old empty processes get pushed
17777            // down to the bottom, so if we are running low on memory we will
17778            // have a better chance at keeping around more cached processes
17779            // instead of a gazillion empty processes.
17780            numEmptyProcs = cachedProcessLimit;
17781        }
17782        int emptyFactor = numEmptyProcs/numSlots;
17783        if (emptyFactor < 1) emptyFactor = 1;
17784        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17785        if (cachedFactor < 1) cachedFactor = 1;
17786        int stepCached = 0;
17787        int stepEmpty = 0;
17788        int numCached = 0;
17789        int numEmpty = 0;
17790        int numTrimming = 0;
17791
17792        mNumNonCachedProcs = 0;
17793        mNumCachedHiddenProcs = 0;
17794
17795        // First update the OOM adjustment for each of the
17796        // application processes based on their current state.
17797        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17798        int nextCachedAdj = curCachedAdj+1;
17799        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17800        int nextEmptyAdj = curEmptyAdj+2;
17801        for (int i=N-1; i>=0; i--) {
17802            ProcessRecord app = mLruProcesses.get(i);
17803            if (!app.killedByAm && app.thread != null) {
17804                app.procStateChanged = false;
17805                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17806
17807                // If we haven't yet assigned the final cached adj
17808                // to the process, do that now.
17809                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17810                    switch (app.curProcState) {
17811                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17812                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17813                            // This process is a cached process holding activities...
17814                            // assign it the next cached value for that type, and then
17815                            // step that cached level.
17816                            app.curRawAdj = curCachedAdj;
17817                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17818                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17819                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17820                                    + ")");
17821                            if (curCachedAdj != nextCachedAdj) {
17822                                stepCached++;
17823                                if (stepCached >= cachedFactor) {
17824                                    stepCached = 0;
17825                                    curCachedAdj = nextCachedAdj;
17826                                    nextCachedAdj += 2;
17827                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17828                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17829                                    }
17830                                }
17831                            }
17832                            break;
17833                        default:
17834                            // For everything else, assign next empty cached process
17835                            // level and bump that up.  Note that this means that
17836                            // long-running services that have dropped down to the
17837                            // cached level will be treated as empty (since their process
17838                            // state is still as a service), which is what we want.
17839                            app.curRawAdj = curEmptyAdj;
17840                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17841                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17842                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17843                                    + ")");
17844                            if (curEmptyAdj != nextEmptyAdj) {
17845                                stepEmpty++;
17846                                if (stepEmpty >= emptyFactor) {
17847                                    stepEmpty = 0;
17848                                    curEmptyAdj = nextEmptyAdj;
17849                                    nextEmptyAdj += 2;
17850                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17851                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17852                                    }
17853                                }
17854                            }
17855                            break;
17856                    }
17857                }
17858
17859                applyOomAdjLocked(app, TOP_APP, true, now);
17860
17861                // Count the number of process types.
17862                switch (app.curProcState) {
17863                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17864                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17865                        mNumCachedHiddenProcs++;
17866                        numCached++;
17867                        if (numCached > cachedProcessLimit) {
17868                            app.kill("cached #" + numCached, true);
17869                        }
17870                        break;
17871                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17872                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17873                                && app.lastActivityTime < oldTime) {
17874                            app.kill("empty for "
17875                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17876                                    / 1000) + "s", true);
17877                        } else {
17878                            numEmpty++;
17879                            if (numEmpty > emptyProcessLimit) {
17880                                app.kill("empty #" + numEmpty, true);
17881                            }
17882                        }
17883                        break;
17884                    default:
17885                        mNumNonCachedProcs++;
17886                        break;
17887                }
17888
17889                if (app.isolated && app.services.size() <= 0) {
17890                    // If this is an isolated process, and there are no
17891                    // services running in it, then the process is no longer
17892                    // needed.  We agressively kill these because we can by
17893                    // definition not re-use the same process again, and it is
17894                    // good to avoid having whatever code was running in them
17895                    // left sitting around after no longer needed.
17896                    app.kill("isolated not needed", true);
17897                }
17898
17899                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17900                        && !app.killedByAm) {
17901                    numTrimming++;
17902                }
17903            }
17904        }
17905
17906        mNumServiceProcs = mNewNumServiceProcs;
17907
17908        // Now determine the memory trimming level of background processes.
17909        // Unfortunately we need to start at the back of the list to do this
17910        // properly.  We only do this if the number of background apps we
17911        // are managing to keep around is less than half the maximum we desire;
17912        // if we are keeping a good number around, we'll let them use whatever
17913        // memory they want.
17914        final int numCachedAndEmpty = numCached + numEmpty;
17915        int memFactor;
17916        if (numCached <= ProcessList.TRIM_CACHED_APPS
17917                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17918            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17919                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17920            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17921                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17922            } else {
17923                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17924            }
17925        } else {
17926            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17927        }
17928        // We always allow the memory level to go up (better).  We only allow it to go
17929        // down if we are in a state where that is allowed, *and* the total number of processes
17930        // has gone down since last time.
17931        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17932                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17933                + " last=" + mLastNumProcesses);
17934        if (memFactor > mLastMemoryLevel) {
17935            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17936                memFactor = mLastMemoryLevel;
17937                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17938            }
17939        }
17940        mLastMemoryLevel = memFactor;
17941        mLastNumProcesses = mLruProcesses.size();
17942        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17943        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17944        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17945            if (mLowRamStartTime == 0) {
17946                mLowRamStartTime = now;
17947            }
17948            int step = 0;
17949            int fgTrimLevel;
17950            switch (memFactor) {
17951                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17952                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17953                    break;
17954                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17955                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17956                    break;
17957                default:
17958                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17959                    break;
17960            }
17961            int factor = numTrimming/3;
17962            int minFactor = 2;
17963            if (mHomeProcess != null) minFactor++;
17964            if (mPreviousProcess != null) minFactor++;
17965            if (factor < minFactor) factor = minFactor;
17966            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17967            for (int i=N-1; i>=0; i--) {
17968                ProcessRecord app = mLruProcesses.get(i);
17969                if (allChanged || app.procStateChanged) {
17970                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17971                    app.procStateChanged = false;
17972                }
17973                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17974                        && !app.killedByAm) {
17975                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17976                        try {
17977                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17978                                    "Trimming memory of " + app.processName
17979                                    + " to " + curLevel);
17980                            app.thread.scheduleTrimMemory(curLevel);
17981                        } catch (RemoteException e) {
17982                        }
17983                        if (false) {
17984                            // For now we won't do this; our memory trimming seems
17985                            // to be good enough at this point that destroying
17986                            // activities causes more harm than good.
17987                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17988                                    && app != mHomeProcess && app != mPreviousProcess) {
17989                                // Need to do this on its own message because the stack may not
17990                                // be in a consistent state at this point.
17991                                // For these apps we will also finish their activities
17992                                // to help them free memory.
17993                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17994                            }
17995                        }
17996                    }
17997                    app.trimMemoryLevel = curLevel;
17998                    step++;
17999                    if (step >= factor) {
18000                        step = 0;
18001                        switch (curLevel) {
18002                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18003                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18004                                break;
18005                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18006                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18007                                break;
18008                        }
18009                    }
18010                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18011                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18012                            && app.thread != null) {
18013                        try {
18014                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18015                                    "Trimming memory of heavy-weight " + app.processName
18016                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18017                            app.thread.scheduleTrimMemory(
18018                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18019                        } catch (RemoteException e) {
18020                        }
18021                    }
18022                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18023                } else {
18024                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18025                            || app.systemNoUi) && app.pendingUiClean) {
18026                        // If this application is now in the background and it
18027                        // had done UI, then give it the special trim level to
18028                        // have it free UI resources.
18029                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18030                        if (app.trimMemoryLevel < level && app.thread != null) {
18031                            try {
18032                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18033                                        "Trimming memory of bg-ui " + app.processName
18034                                        + " to " + level);
18035                                app.thread.scheduleTrimMemory(level);
18036                            } catch (RemoteException e) {
18037                            }
18038                        }
18039                        app.pendingUiClean = false;
18040                    }
18041                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18042                        try {
18043                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18044                                    "Trimming memory of fg " + app.processName
18045                                    + " to " + fgTrimLevel);
18046                            app.thread.scheduleTrimMemory(fgTrimLevel);
18047                        } catch (RemoteException e) {
18048                        }
18049                    }
18050                    app.trimMemoryLevel = fgTrimLevel;
18051                }
18052            }
18053        } else {
18054            if (mLowRamStartTime != 0) {
18055                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18056                mLowRamStartTime = 0;
18057            }
18058            for (int i=N-1; i>=0; i--) {
18059                ProcessRecord app = mLruProcesses.get(i);
18060                if (allChanged || app.procStateChanged) {
18061                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18062                    app.procStateChanged = false;
18063                }
18064                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18065                        || app.systemNoUi) && app.pendingUiClean) {
18066                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18067                            && app.thread != null) {
18068                        try {
18069                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18070                                    "Trimming memory of ui hidden " + app.processName
18071                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18072                            app.thread.scheduleTrimMemory(
18073                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18074                        } catch (RemoteException e) {
18075                        }
18076                    }
18077                    app.pendingUiClean = false;
18078                }
18079                app.trimMemoryLevel = 0;
18080            }
18081        }
18082
18083        if (mAlwaysFinishActivities) {
18084            // Need to do this on its own message because the stack may not
18085            // be in a consistent state at this point.
18086            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18087        }
18088
18089        if (allChanged) {
18090            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18091        }
18092
18093        if (mProcessStats.shouldWriteNowLocked(now)) {
18094            mHandler.post(new Runnable() {
18095                @Override public void run() {
18096                    synchronized (ActivityManagerService.this) {
18097                        mProcessStats.writeStateAsyncLocked();
18098                    }
18099                }
18100            });
18101        }
18102
18103        if (DEBUG_OOM_ADJ) {
18104            if (false) {
18105                RuntimeException here = new RuntimeException("here");
18106                here.fillInStackTrace();
18107                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18108            } else {
18109                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18110            }
18111        }
18112    }
18113
18114    final void trimApplications() {
18115        synchronized (this) {
18116            int i;
18117
18118            // First remove any unused application processes whose package
18119            // has been removed.
18120            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18121                final ProcessRecord app = mRemovedProcesses.get(i);
18122                if (app.activities.size() == 0
18123                        && app.curReceiver == null && app.services.size() == 0) {
18124                    Slog.i(
18125                        TAG, "Exiting empty application process "
18126                        + app.processName + " ("
18127                        + (app.thread != null ? app.thread.asBinder() : null)
18128                        + ")\n");
18129                    if (app.pid > 0 && app.pid != MY_PID) {
18130                        app.kill("empty", false);
18131                    } else {
18132                        try {
18133                            app.thread.scheduleExit();
18134                        } catch (Exception e) {
18135                            // Ignore exceptions.
18136                        }
18137                    }
18138                    cleanUpApplicationRecordLocked(app, false, true, -1);
18139                    mRemovedProcesses.remove(i);
18140
18141                    if (app.persistent) {
18142                        addAppLocked(app.info, false, null /* ABI override */);
18143                    }
18144                }
18145            }
18146
18147            // Now update the oom adj for all processes.
18148            updateOomAdjLocked();
18149        }
18150    }
18151
18152    /** This method sends the specified signal to each of the persistent apps */
18153    public void signalPersistentProcesses(int sig) throws RemoteException {
18154        if (sig != Process.SIGNAL_USR1) {
18155            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18156        }
18157
18158        synchronized (this) {
18159            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18160                    != PackageManager.PERMISSION_GRANTED) {
18161                throw new SecurityException("Requires permission "
18162                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18163            }
18164
18165            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18166                ProcessRecord r = mLruProcesses.get(i);
18167                if (r.thread != null && r.persistent) {
18168                    Process.sendSignal(r.pid, sig);
18169                }
18170            }
18171        }
18172    }
18173
18174    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18175        if (proc == null || proc == mProfileProc) {
18176            proc = mProfileProc;
18177            profileType = mProfileType;
18178            clearProfilerLocked();
18179        }
18180        if (proc == null) {
18181            return;
18182        }
18183        try {
18184            proc.thread.profilerControl(false, null, profileType);
18185        } catch (RemoteException e) {
18186            throw new IllegalStateException("Process disappeared");
18187        }
18188    }
18189
18190    private void clearProfilerLocked() {
18191        if (mProfileFd != null) {
18192            try {
18193                mProfileFd.close();
18194            } catch (IOException e) {
18195            }
18196        }
18197        mProfileApp = null;
18198        mProfileProc = null;
18199        mProfileFile = null;
18200        mProfileType = 0;
18201        mAutoStopProfiler = false;
18202        mSamplingInterval = 0;
18203    }
18204
18205    public boolean profileControl(String process, int userId, boolean start,
18206            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18207
18208        try {
18209            synchronized (this) {
18210                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18211                // its own permission.
18212                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18213                        != PackageManager.PERMISSION_GRANTED) {
18214                    throw new SecurityException("Requires permission "
18215                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18216                }
18217
18218                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18219                    throw new IllegalArgumentException("null profile info or fd");
18220                }
18221
18222                ProcessRecord proc = null;
18223                if (process != null) {
18224                    proc = findProcessLocked(process, userId, "profileControl");
18225                }
18226
18227                if (start && (proc == null || proc.thread == null)) {
18228                    throw new IllegalArgumentException("Unknown process: " + process);
18229                }
18230
18231                if (start) {
18232                    stopProfilerLocked(null, 0);
18233                    setProfileApp(proc.info, proc.processName, profilerInfo);
18234                    mProfileProc = proc;
18235                    mProfileType = profileType;
18236                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18237                    try {
18238                        fd = fd.dup();
18239                    } catch (IOException e) {
18240                        fd = null;
18241                    }
18242                    profilerInfo.profileFd = fd;
18243                    proc.thread.profilerControl(start, profilerInfo, profileType);
18244                    fd = null;
18245                    mProfileFd = null;
18246                } else {
18247                    stopProfilerLocked(proc, profileType);
18248                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18249                        try {
18250                            profilerInfo.profileFd.close();
18251                        } catch (IOException e) {
18252                        }
18253                    }
18254                }
18255
18256                return true;
18257            }
18258        } catch (RemoteException e) {
18259            throw new IllegalStateException("Process disappeared");
18260        } finally {
18261            if (profilerInfo != null && profilerInfo.profileFd != null) {
18262                try {
18263                    profilerInfo.profileFd.close();
18264                } catch (IOException e) {
18265                }
18266            }
18267        }
18268    }
18269
18270    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18271        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18272                userId, true, ALLOW_FULL_ONLY, callName, null);
18273        ProcessRecord proc = null;
18274        try {
18275            int pid = Integer.parseInt(process);
18276            synchronized (mPidsSelfLocked) {
18277                proc = mPidsSelfLocked.get(pid);
18278            }
18279        } catch (NumberFormatException e) {
18280        }
18281
18282        if (proc == null) {
18283            ArrayMap<String, SparseArray<ProcessRecord>> all
18284                    = mProcessNames.getMap();
18285            SparseArray<ProcessRecord> procs = all.get(process);
18286            if (procs != null && procs.size() > 0) {
18287                proc = procs.valueAt(0);
18288                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18289                    for (int i=1; i<procs.size(); i++) {
18290                        ProcessRecord thisProc = procs.valueAt(i);
18291                        if (thisProc.userId == userId) {
18292                            proc = thisProc;
18293                            break;
18294                        }
18295                    }
18296                }
18297            }
18298        }
18299
18300        return proc;
18301    }
18302
18303    public boolean dumpHeap(String process, int userId, boolean managed,
18304            String path, ParcelFileDescriptor fd) throws RemoteException {
18305
18306        try {
18307            synchronized (this) {
18308                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18309                // its own permission (same as profileControl).
18310                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18311                        != PackageManager.PERMISSION_GRANTED) {
18312                    throw new SecurityException("Requires permission "
18313                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18314                }
18315
18316                if (fd == null) {
18317                    throw new IllegalArgumentException("null fd");
18318                }
18319
18320                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18321                if (proc == null || proc.thread == null) {
18322                    throw new IllegalArgumentException("Unknown process: " + process);
18323                }
18324
18325                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18326                if (!isDebuggable) {
18327                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18328                        throw new SecurityException("Process not debuggable: " + proc);
18329                    }
18330                }
18331
18332                proc.thread.dumpHeap(managed, path, fd);
18333                fd = null;
18334                return true;
18335            }
18336        } catch (RemoteException e) {
18337            throw new IllegalStateException("Process disappeared");
18338        } finally {
18339            if (fd != null) {
18340                try {
18341                    fd.close();
18342                } catch (IOException e) {
18343                }
18344            }
18345        }
18346    }
18347
18348    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18349    public void monitor() {
18350        synchronized (this) { }
18351    }
18352
18353    void onCoreSettingsChange(Bundle settings) {
18354        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18355            ProcessRecord processRecord = mLruProcesses.get(i);
18356            try {
18357                if (processRecord.thread != null) {
18358                    processRecord.thread.setCoreSettings(settings);
18359                }
18360            } catch (RemoteException re) {
18361                /* ignore */
18362            }
18363        }
18364    }
18365
18366    // Multi-user methods
18367
18368    /**
18369     * Start user, if its not already running, but don't bring it to foreground.
18370     */
18371    @Override
18372    public boolean startUserInBackground(final int userId) {
18373        return startUser(userId, /* foreground */ false);
18374    }
18375
18376    /**
18377     * Start user, if its not already running, and bring it to foreground.
18378     */
18379    boolean startUserInForeground(final int userId, Dialog dlg) {
18380        boolean result = startUser(userId, /* foreground */ true);
18381        dlg.dismiss();
18382        return result;
18383    }
18384
18385    /**
18386     * Refreshes the list of users related to the current user when either a
18387     * user switch happens or when a new related user is started in the
18388     * background.
18389     */
18390    private void updateCurrentProfileIdsLocked() {
18391        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18392                mCurrentUserId, false /* enabledOnly */);
18393        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18394        for (int i = 0; i < currentProfileIds.length; i++) {
18395            currentProfileIds[i] = profiles.get(i).id;
18396        }
18397        mCurrentProfileIds = currentProfileIds;
18398
18399        synchronized (mUserProfileGroupIdsSelfLocked) {
18400            mUserProfileGroupIdsSelfLocked.clear();
18401            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18402            for (int i = 0; i < users.size(); i++) {
18403                UserInfo user = users.get(i);
18404                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18405                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18406                }
18407            }
18408        }
18409    }
18410
18411    private Set<Integer> getProfileIdsLocked(int userId) {
18412        Set<Integer> userIds = new HashSet<Integer>();
18413        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18414                userId, false /* enabledOnly */);
18415        for (UserInfo user : profiles) {
18416            userIds.add(Integer.valueOf(user.id));
18417        }
18418        return userIds;
18419    }
18420
18421    @Override
18422    public boolean switchUser(final int userId) {
18423        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18424        String userName;
18425        synchronized (this) {
18426            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18427            if (userInfo == null) {
18428                Slog.w(TAG, "No user info for user #" + userId);
18429                return false;
18430            }
18431            if (userInfo.isManagedProfile()) {
18432                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18433                return false;
18434            }
18435            userName = userInfo.name;
18436            mTargetUserId = userId;
18437        }
18438        mHandler.removeMessages(START_USER_SWITCH_MSG);
18439        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18440        return true;
18441    }
18442
18443    private void showUserSwitchDialog(int userId, String userName) {
18444        // The dialog will show and then initiate the user switch by calling startUserInForeground
18445        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18446                true /* above system */);
18447        d.show();
18448    }
18449
18450    private boolean startUser(final int userId, final boolean foreground) {
18451        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18452                != PackageManager.PERMISSION_GRANTED) {
18453            String msg = "Permission Denial: switchUser() from pid="
18454                    + Binder.getCallingPid()
18455                    + ", uid=" + Binder.getCallingUid()
18456                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18457            Slog.w(TAG, msg);
18458            throw new SecurityException(msg);
18459        }
18460
18461        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18462
18463        final long ident = Binder.clearCallingIdentity();
18464        try {
18465            synchronized (this) {
18466                final int oldUserId = mCurrentUserId;
18467                if (oldUserId == userId) {
18468                    return true;
18469                }
18470
18471                mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18472
18473                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18474                if (userInfo == null) {
18475                    Slog.w(TAG, "No user info for user #" + userId);
18476                    return false;
18477                }
18478                if (foreground && userInfo.isManagedProfile()) {
18479                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18480                    return false;
18481                }
18482
18483                if (foreground) {
18484                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18485                            R.anim.screen_user_enter);
18486                }
18487
18488                boolean needStart = false;
18489
18490                // If the user we are switching to is not currently started, then
18491                // we need to start it now.
18492                if (mStartedUsers.get(userId) == null) {
18493                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18494                    updateStartedUserArrayLocked();
18495                    needStart = true;
18496                }
18497
18498                final Integer userIdInt = Integer.valueOf(userId);
18499                mUserLru.remove(userIdInt);
18500                mUserLru.add(userIdInt);
18501
18502                if (foreground) {
18503                    mCurrentUserId = userId;
18504                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18505                    updateCurrentProfileIdsLocked();
18506                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18507                    // Once the internal notion of the active user has switched, we lock the device
18508                    // with the option to show the user switcher on the keyguard.
18509                    mWindowManager.lockNow(null);
18510                } else {
18511                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18512                    updateCurrentProfileIdsLocked();
18513                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18514                    mUserLru.remove(currentUserIdInt);
18515                    mUserLru.add(currentUserIdInt);
18516                }
18517
18518                final UserStartedState uss = mStartedUsers.get(userId);
18519
18520                // Make sure user is in the started state.  If it is currently
18521                // stopping, we need to knock that off.
18522                if (uss.mState == UserStartedState.STATE_STOPPING) {
18523                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18524                    // so we can just fairly silently bring the user back from
18525                    // the almost-dead.
18526                    uss.mState = UserStartedState.STATE_RUNNING;
18527                    updateStartedUserArrayLocked();
18528                    needStart = true;
18529                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18530                    // This means ACTION_SHUTDOWN has been sent, so we will
18531                    // need to treat this as a new boot of the user.
18532                    uss.mState = UserStartedState.STATE_BOOTING;
18533                    updateStartedUserArrayLocked();
18534                    needStart = true;
18535                }
18536
18537                if (uss.mState == UserStartedState.STATE_BOOTING) {
18538                    // Booting up a new user, need to tell system services about it.
18539                    // Note that this is on the same handler as scheduling of broadcasts,
18540                    // which is important because it needs to go first.
18541                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18542                }
18543
18544                if (foreground) {
18545                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18546                            oldUserId));
18547                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18548                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18549                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18550                            oldUserId, userId, uss));
18551                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18552                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18553                }
18554
18555                if (needStart) {
18556                    // Send USER_STARTED broadcast
18557                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18558                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18559                            | Intent.FLAG_RECEIVER_FOREGROUND);
18560                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18561                    broadcastIntentLocked(null, null, intent,
18562                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18563                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18564                }
18565
18566                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18567                    if (userId != UserHandle.USER_OWNER) {
18568                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18569                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18570                        broadcastIntentLocked(null, null, intent, null,
18571                                new IIntentReceiver.Stub() {
18572                                    public void performReceive(Intent intent, int resultCode,
18573                                            String data, Bundle extras, boolean ordered,
18574                                            boolean sticky, int sendingUser) {
18575                                        onUserInitialized(uss, foreground, oldUserId, userId);
18576                                    }
18577                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18578                                true, false, MY_PID, Process.SYSTEM_UID,
18579                                userId);
18580                        uss.initializing = true;
18581                    } else {
18582                        getUserManagerLocked().makeInitialized(userInfo.id);
18583                    }
18584                }
18585
18586                if (foreground) {
18587                    if (!uss.initializing) {
18588                        moveUserToForeground(uss, oldUserId, userId);
18589                    }
18590                } else {
18591                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18592                }
18593
18594                if (needStart) {
18595                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18596                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18597                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18598                    broadcastIntentLocked(null, null, intent,
18599                            null, new IIntentReceiver.Stub() {
18600                                @Override
18601                                public void performReceive(Intent intent, int resultCode, String data,
18602                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18603                                        throws RemoteException {
18604                                }
18605                            }, 0, null, null,
18606                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18607                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18608                }
18609            }
18610        } finally {
18611            Binder.restoreCallingIdentity(ident);
18612        }
18613
18614        return true;
18615    }
18616
18617    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18618        long ident = Binder.clearCallingIdentity();
18619        try {
18620            Intent intent;
18621            if (oldUserId >= 0) {
18622                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18623                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18624                int count = profiles.size();
18625                for (int i = 0; i < count; i++) {
18626                    int profileUserId = profiles.get(i).id;
18627                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18628                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18629                            | Intent.FLAG_RECEIVER_FOREGROUND);
18630                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18631                    broadcastIntentLocked(null, null, intent,
18632                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18633                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18634                }
18635            }
18636            if (newUserId >= 0) {
18637                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18638                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18639                int count = profiles.size();
18640                for (int i = 0; i < count; i++) {
18641                    int profileUserId = profiles.get(i).id;
18642                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18643                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18644                            | Intent.FLAG_RECEIVER_FOREGROUND);
18645                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18646                    broadcastIntentLocked(null, null, intent,
18647                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18648                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18649                }
18650                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18651                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18652                        | Intent.FLAG_RECEIVER_FOREGROUND);
18653                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18654                broadcastIntentLocked(null, null, intent,
18655                        null, null, 0, null, null,
18656                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18657                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18658            }
18659        } finally {
18660            Binder.restoreCallingIdentity(ident);
18661        }
18662    }
18663
18664    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18665            final int newUserId) {
18666        final int N = mUserSwitchObservers.beginBroadcast();
18667        if (N > 0) {
18668            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18669                int mCount = 0;
18670                @Override
18671                public void sendResult(Bundle data) throws RemoteException {
18672                    synchronized (ActivityManagerService.this) {
18673                        if (mCurUserSwitchCallback == this) {
18674                            mCount++;
18675                            if (mCount == N) {
18676                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18677                            }
18678                        }
18679                    }
18680                }
18681            };
18682            synchronized (this) {
18683                uss.switching = true;
18684                mCurUserSwitchCallback = callback;
18685            }
18686            for (int i=0; i<N; i++) {
18687                try {
18688                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18689                            newUserId, callback);
18690                } catch (RemoteException e) {
18691                }
18692            }
18693        } else {
18694            synchronized (this) {
18695                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18696            }
18697        }
18698        mUserSwitchObservers.finishBroadcast();
18699    }
18700
18701    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18702        synchronized (this) {
18703            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18704            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18705        }
18706    }
18707
18708    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18709        mCurUserSwitchCallback = null;
18710        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18711        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18712                oldUserId, newUserId, uss));
18713    }
18714
18715    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18716        synchronized (this) {
18717            if (foreground) {
18718                moveUserToForeground(uss, oldUserId, newUserId);
18719            }
18720        }
18721
18722        completeSwitchAndInitalize(uss, newUserId, true, false);
18723    }
18724
18725    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18726        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18727        if (homeInFront) {
18728            startHomeActivityLocked(newUserId, "moveUserToFroreground");
18729        } else {
18730            mStackSupervisor.resumeTopActivitiesLocked();
18731        }
18732        EventLogTags.writeAmSwitchUser(newUserId);
18733        getUserManagerLocked().userForeground(newUserId);
18734        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18735    }
18736
18737    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18738        completeSwitchAndInitalize(uss, newUserId, false, true);
18739    }
18740
18741    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18742            boolean clearInitializing, boolean clearSwitching) {
18743        boolean unfrozen = false;
18744        synchronized (this) {
18745            if (clearInitializing) {
18746                uss.initializing = false;
18747                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18748            }
18749            if (clearSwitching) {
18750                uss.switching = false;
18751            }
18752            if (!uss.switching && !uss.initializing) {
18753                mWindowManager.stopFreezingScreen();
18754                unfrozen = true;
18755            }
18756        }
18757        if (unfrozen) {
18758            final int N = mUserSwitchObservers.beginBroadcast();
18759            for (int i=0; i<N; i++) {
18760                try {
18761                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18762                } catch (RemoteException e) {
18763                }
18764            }
18765            mUserSwitchObservers.finishBroadcast();
18766        }
18767        stopGuestUserIfBackground();
18768    }
18769
18770    /**
18771     * Stops the guest user if it has gone to the background.
18772     */
18773    private void stopGuestUserIfBackground() {
18774        synchronized (this) {
18775            final int num = mUserLru.size();
18776            for (int i = 0; i < num; i++) {
18777                Integer oldUserId = mUserLru.get(i);
18778                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18779                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
18780                        || oldUss.mState == UserStartedState.STATE_STOPPING
18781                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18782                    continue;
18783                }
18784                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
18785                if (userInfo.isGuest()) {
18786                    // This is a user to be stopped.
18787                    stopUserLocked(oldUserId, null);
18788                    break;
18789                }
18790            }
18791        }
18792    }
18793
18794    void scheduleStartProfilesLocked() {
18795        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18796            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18797                    DateUtils.SECOND_IN_MILLIS);
18798        }
18799    }
18800
18801    void startProfilesLocked() {
18802        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18803        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18804                mCurrentUserId, false /* enabledOnly */);
18805        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18806        for (UserInfo user : profiles) {
18807            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18808                    && user.id != mCurrentUserId) {
18809                toStart.add(user);
18810            }
18811        }
18812        final int n = toStart.size();
18813        int i = 0;
18814        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18815            startUserInBackground(toStart.get(i).id);
18816        }
18817        if (i < n) {
18818            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18819        }
18820    }
18821
18822    void finishUserBoot(UserStartedState uss) {
18823        synchronized (this) {
18824            if (uss.mState == UserStartedState.STATE_BOOTING
18825                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18826                uss.mState = UserStartedState.STATE_RUNNING;
18827                final int userId = uss.mHandle.getIdentifier();
18828                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18829                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18830                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18831                broadcastIntentLocked(null, null, intent,
18832                        null, null, 0, null, null,
18833                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18834                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18835            }
18836        }
18837    }
18838
18839    void finishUserSwitch(UserStartedState uss) {
18840        synchronized (this) {
18841            finishUserBoot(uss);
18842
18843            startProfilesLocked();
18844
18845            int num = mUserLru.size();
18846            int i = 0;
18847            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18848                Integer oldUserId = mUserLru.get(i);
18849                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18850                if (oldUss == null) {
18851                    // Shouldn't happen, but be sane if it does.
18852                    mUserLru.remove(i);
18853                    num--;
18854                    continue;
18855                }
18856                if (oldUss.mState == UserStartedState.STATE_STOPPING
18857                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18858                    // This user is already stopping, doesn't count.
18859                    num--;
18860                    i++;
18861                    continue;
18862                }
18863                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18864                    // Owner and current can't be stopped, but count as running.
18865                    i++;
18866                    continue;
18867                }
18868                // This is a user to be stopped.
18869                stopUserLocked(oldUserId, null);
18870                num--;
18871                i++;
18872            }
18873        }
18874    }
18875
18876    @Override
18877    public int stopUser(final int userId, final IStopUserCallback callback) {
18878        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18879                != PackageManager.PERMISSION_GRANTED) {
18880            String msg = "Permission Denial: switchUser() from pid="
18881                    + Binder.getCallingPid()
18882                    + ", uid=" + Binder.getCallingUid()
18883                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18884            Slog.w(TAG, msg);
18885            throw new SecurityException(msg);
18886        }
18887        if (userId <= 0) {
18888            throw new IllegalArgumentException("Can't stop primary user " + userId);
18889        }
18890        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18891        synchronized (this) {
18892            return stopUserLocked(userId, callback);
18893        }
18894    }
18895
18896    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18897        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18898        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18899            return ActivityManager.USER_OP_IS_CURRENT;
18900        }
18901
18902        final UserStartedState uss = mStartedUsers.get(userId);
18903        if (uss == null) {
18904            // User is not started, nothing to do...  but we do need to
18905            // callback if requested.
18906            if (callback != null) {
18907                mHandler.post(new Runnable() {
18908                    @Override
18909                    public void run() {
18910                        try {
18911                            callback.userStopped(userId);
18912                        } catch (RemoteException e) {
18913                        }
18914                    }
18915                });
18916            }
18917            return ActivityManager.USER_OP_SUCCESS;
18918        }
18919
18920        if (callback != null) {
18921            uss.mStopCallbacks.add(callback);
18922        }
18923
18924        if (uss.mState != UserStartedState.STATE_STOPPING
18925                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18926            uss.mState = UserStartedState.STATE_STOPPING;
18927            updateStartedUserArrayLocked();
18928
18929            long ident = Binder.clearCallingIdentity();
18930            try {
18931                // We are going to broadcast ACTION_USER_STOPPING and then
18932                // once that is done send a final ACTION_SHUTDOWN and then
18933                // stop the user.
18934                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18935                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18936                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18937                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18938                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18939                // This is the result receiver for the final shutdown broadcast.
18940                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18941                    @Override
18942                    public void performReceive(Intent intent, int resultCode, String data,
18943                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18944                        finishUserStop(uss);
18945                    }
18946                };
18947                // This is the result receiver for the initial stopping broadcast.
18948                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18949                    @Override
18950                    public void performReceive(Intent intent, int resultCode, String data,
18951                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18952                        // On to the next.
18953                        synchronized (ActivityManagerService.this) {
18954                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18955                                // Whoops, we are being started back up.  Abort, abort!
18956                                return;
18957                            }
18958                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18959                        }
18960                        mBatteryStatsService.noteEvent(
18961                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18962                                Integer.toString(userId), userId);
18963                        mSystemServiceManager.stopUser(userId);
18964                        broadcastIntentLocked(null, null, shutdownIntent,
18965                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18966                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18967                    }
18968                };
18969                // Kick things off.
18970                broadcastIntentLocked(null, null, stoppingIntent,
18971                        null, stoppingReceiver, 0, null, null,
18972                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18973                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18974            } finally {
18975                Binder.restoreCallingIdentity(ident);
18976            }
18977        }
18978
18979        return ActivityManager.USER_OP_SUCCESS;
18980    }
18981
18982    void finishUserStop(UserStartedState uss) {
18983        final int userId = uss.mHandle.getIdentifier();
18984        boolean stopped;
18985        ArrayList<IStopUserCallback> callbacks;
18986        synchronized (this) {
18987            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18988            if (mStartedUsers.get(userId) != uss) {
18989                stopped = false;
18990            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18991                stopped = false;
18992            } else {
18993                stopped = true;
18994                // User can no longer run.
18995                mStartedUsers.remove(userId);
18996                mUserLru.remove(Integer.valueOf(userId));
18997                updateStartedUserArrayLocked();
18998
18999                // Clean up all state and processes associated with the user.
19000                // Kill all the processes for the user.
19001                forceStopUserLocked(userId, "finish user");
19002            }
19003
19004            // Explicitly remove the old information in mRecentTasks.
19005            mRecentTasks.removeTasksForUserLocked(userId);
19006        }
19007
19008        for (int i=0; i<callbacks.size(); i++) {
19009            try {
19010                if (stopped) callbacks.get(i).userStopped(userId);
19011                else callbacks.get(i).userStopAborted(userId);
19012            } catch (RemoteException e) {
19013            }
19014        }
19015
19016        if (stopped) {
19017            mSystemServiceManager.cleanupUser(userId);
19018            synchronized (this) {
19019                mStackSupervisor.removeUserLocked(userId);
19020            }
19021        }
19022    }
19023
19024    @Override
19025    public UserInfo getCurrentUser() {
19026        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19027                != PackageManager.PERMISSION_GRANTED) && (
19028                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19029                != PackageManager.PERMISSION_GRANTED)) {
19030            String msg = "Permission Denial: getCurrentUser() from pid="
19031                    + Binder.getCallingPid()
19032                    + ", uid=" + Binder.getCallingUid()
19033                    + " requires " + INTERACT_ACROSS_USERS;
19034            Slog.w(TAG, msg);
19035            throw new SecurityException(msg);
19036        }
19037        synchronized (this) {
19038            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19039            return getUserManagerLocked().getUserInfo(userId);
19040        }
19041    }
19042
19043    int getCurrentUserIdLocked() {
19044        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19045    }
19046
19047    @Override
19048    public boolean isUserRunning(int userId, boolean orStopped) {
19049        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19050                != PackageManager.PERMISSION_GRANTED) {
19051            String msg = "Permission Denial: isUserRunning() from pid="
19052                    + Binder.getCallingPid()
19053                    + ", uid=" + Binder.getCallingUid()
19054                    + " requires " + INTERACT_ACROSS_USERS;
19055            Slog.w(TAG, msg);
19056            throw new SecurityException(msg);
19057        }
19058        synchronized (this) {
19059            return isUserRunningLocked(userId, orStopped);
19060        }
19061    }
19062
19063    boolean isUserRunningLocked(int userId, boolean orStopped) {
19064        UserStartedState state = mStartedUsers.get(userId);
19065        if (state == null) {
19066            return false;
19067        }
19068        if (orStopped) {
19069            return true;
19070        }
19071        return state.mState != UserStartedState.STATE_STOPPING
19072                && state.mState != UserStartedState.STATE_SHUTDOWN;
19073    }
19074
19075    @Override
19076    public int[] getRunningUserIds() {
19077        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19078                != PackageManager.PERMISSION_GRANTED) {
19079            String msg = "Permission Denial: isUserRunning() from pid="
19080                    + Binder.getCallingPid()
19081                    + ", uid=" + Binder.getCallingUid()
19082                    + " requires " + INTERACT_ACROSS_USERS;
19083            Slog.w(TAG, msg);
19084            throw new SecurityException(msg);
19085        }
19086        synchronized (this) {
19087            return mStartedUserArray;
19088        }
19089    }
19090
19091    private void updateStartedUserArrayLocked() {
19092        int num = 0;
19093        for (int i=0; i<mStartedUsers.size();  i++) {
19094            UserStartedState uss = mStartedUsers.valueAt(i);
19095            // This list does not include stopping users.
19096            if (uss.mState != UserStartedState.STATE_STOPPING
19097                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19098                num++;
19099            }
19100        }
19101        mStartedUserArray = new int[num];
19102        num = 0;
19103        for (int i=0; i<mStartedUsers.size();  i++) {
19104            UserStartedState uss = mStartedUsers.valueAt(i);
19105            if (uss.mState != UserStartedState.STATE_STOPPING
19106                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19107                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19108                num++;
19109            }
19110        }
19111    }
19112
19113    @Override
19114    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19115        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19116                != PackageManager.PERMISSION_GRANTED) {
19117            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19118                    + Binder.getCallingPid()
19119                    + ", uid=" + Binder.getCallingUid()
19120                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19121            Slog.w(TAG, msg);
19122            throw new SecurityException(msg);
19123        }
19124
19125        mUserSwitchObservers.register(observer);
19126    }
19127
19128    @Override
19129    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19130        mUserSwitchObservers.unregister(observer);
19131    }
19132
19133    private boolean userExists(int userId) {
19134        if (userId == 0) {
19135            return true;
19136        }
19137        UserManagerService ums = getUserManagerLocked();
19138        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19139    }
19140
19141    int[] getUsersLocked() {
19142        UserManagerService ums = getUserManagerLocked();
19143        return ums != null ? ums.getUserIds() : new int[] { 0 };
19144    }
19145
19146    UserManagerService getUserManagerLocked() {
19147        if (mUserManager == null) {
19148            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19149            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19150        }
19151        return mUserManager;
19152    }
19153
19154    private int applyUserId(int uid, int userId) {
19155        return UserHandle.getUid(userId, uid);
19156    }
19157
19158    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19159        if (info == null) return null;
19160        ApplicationInfo newInfo = new ApplicationInfo(info);
19161        newInfo.uid = applyUserId(info.uid, userId);
19162        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19163                + info.packageName;
19164        return newInfo;
19165    }
19166
19167    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19168        if (aInfo == null
19169                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19170            return aInfo;
19171        }
19172
19173        ActivityInfo info = new ActivityInfo(aInfo);
19174        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19175        return info;
19176    }
19177
19178    private final class LocalService extends ActivityManagerInternal {
19179        @Override
19180        public void onWakefulnessChanged(int wakefulness) {
19181            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19182        }
19183
19184        @Override
19185        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19186                String processName, String abiOverride, int uid, Runnable crashHandler) {
19187            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19188                    processName, abiOverride, uid, crashHandler);
19189        }
19190    }
19191
19192    /**
19193     * An implementation of IAppTask, that allows an app to manage its own tasks via
19194     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19195     * only the process that calls getAppTasks() can call the AppTask methods.
19196     */
19197    class AppTaskImpl extends IAppTask.Stub {
19198        private int mTaskId;
19199        private int mCallingUid;
19200
19201        public AppTaskImpl(int taskId, int callingUid) {
19202            mTaskId = taskId;
19203            mCallingUid = callingUid;
19204        }
19205
19206        private void checkCaller() {
19207            if (mCallingUid != Binder.getCallingUid()) {
19208                throw new SecurityException("Caller " + mCallingUid
19209                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19210            }
19211        }
19212
19213        @Override
19214        public void finishAndRemoveTask() {
19215            checkCaller();
19216
19217            synchronized (ActivityManagerService.this) {
19218                long origId = Binder.clearCallingIdentity();
19219                try {
19220                    if (!removeTaskByIdLocked(mTaskId, false)) {
19221                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19222                    }
19223                } finally {
19224                    Binder.restoreCallingIdentity(origId);
19225                }
19226            }
19227        }
19228
19229        @Override
19230        public ActivityManager.RecentTaskInfo getTaskInfo() {
19231            checkCaller();
19232
19233            synchronized (ActivityManagerService.this) {
19234                long origId = Binder.clearCallingIdentity();
19235                try {
19236                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19237                    if (tr == null) {
19238                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19239                    }
19240                    return createRecentTaskInfoFromTaskRecord(tr);
19241                } finally {
19242                    Binder.restoreCallingIdentity(origId);
19243                }
19244            }
19245        }
19246
19247        @Override
19248        public void moveToFront() {
19249            checkCaller();
19250            // Will bring task to front if it already has a root activity.
19251            startActivityFromRecentsInner(mTaskId, null);
19252        }
19253
19254        @Override
19255        public int startActivity(IBinder whoThread, String callingPackage,
19256                Intent intent, String resolvedType, Bundle options) {
19257            checkCaller();
19258
19259            int callingUser = UserHandle.getCallingUserId();
19260            TaskRecord tr;
19261            IApplicationThread appThread;
19262            synchronized (ActivityManagerService.this) {
19263                tr = mRecentTasks.taskForIdLocked(mTaskId);
19264                if (tr == null) {
19265                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19266                }
19267                appThread = ApplicationThreadNative.asInterface(whoThread);
19268                if (appThread == null) {
19269                    throw new IllegalArgumentException("Bad app thread " + appThread);
19270                }
19271            }
19272            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19273                    resolvedType, null, null, null, null, 0, 0, null, null,
19274                    null, options, callingUser, null, tr);
19275        }
19276
19277        @Override
19278        public void setExcludeFromRecents(boolean exclude) {
19279            checkCaller();
19280
19281            synchronized (ActivityManagerService.this) {
19282                long origId = Binder.clearCallingIdentity();
19283                try {
19284                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19285                    if (tr == null) {
19286                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19287                    }
19288                    Intent intent = tr.getBaseIntent();
19289                    if (exclude) {
19290                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19291                    } else {
19292                        intent.setFlags(intent.getFlags()
19293                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19294                    }
19295                } finally {
19296                    Binder.restoreCallingIdentity(origId);
19297                }
19298            }
19299        }
19300    }
19301}
19302