ActivityManagerService.java revision d052a9416ae3f7e42fc1e7de0740021df385ee48
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.os.BackgroundThread;
65import com.android.internal.os.BatteryStatsImpl;
66import com.android.internal.os.ProcessCpuTracker;
67import com.android.internal.os.TransferPipe;
68import com.android.internal.os.Zygote;
69import com.android.internal.util.FastPrintWriter;
70import com.android.internal.util.FastXmlSerializer;
71import com.android.internal.util.MemInfoReader;
72import com.android.internal.util.Preconditions;
73import com.android.server.AppOpsService;
74import com.android.server.AttributeCache;
75import com.android.server.IntentResolver;
76import com.android.server.LocalServices;
77import com.android.server.ServiceThread;
78import com.android.server.SystemService;
79import com.android.server.SystemServiceManager;
80import com.android.server.Watchdog;
81import com.android.server.am.ActivityStack.ActivityState;
82import com.android.server.firewall.IntentFirewall;
83import com.android.server.pm.Installer;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203
204import dalvik.system.VMRuntime;
205
206import java.io.BufferedInputStream;
207import java.io.BufferedOutputStream;
208import java.io.DataInputStream;
209import java.io.DataOutputStream;
210import java.io.File;
211import java.io.FileDescriptor;
212import java.io.FileInputStream;
213import java.io.FileNotFoundException;
214import java.io.FileOutputStream;
215import java.io.IOException;
216import java.io.InputStreamReader;
217import java.io.PrintWriter;
218import java.io.StringWriter;
219import java.lang.ref.WeakReference;
220import java.util.ArrayList;
221import java.util.Arrays;
222import java.util.Collections;
223import java.util.Comparator;
224import java.util.HashMap;
225import java.util.HashSet;
226import java.util.Iterator;
227import java.util.List;
228import java.util.Locale;
229import java.util.Map;
230import java.util.Set;
231import java.util.concurrent.atomic.AtomicBoolean;
232import java.util.concurrent.atomic.AtomicLong;
233
234public final class ActivityManagerService extends ActivityManagerNative
235        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237    private static final String USER_DATA_DIR = "/data/user/";
238    // File that stores last updated system version and called preboot receivers
239    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241    static final String TAG = "ActivityManager";
242    static final String TAG_MU = "ActivityManagerServiceMU";
243    static final boolean DEBUG = false;
244    static final boolean localLOGV = DEBUG;
245    static final boolean DEBUG_BACKUP = localLOGV || false;
246    static final boolean DEBUG_BROADCAST = localLOGV || false;
247    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_CLEANUP = localLOGV || false;
250    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251    static final boolean DEBUG_FOCUS = false;
252    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253    static final boolean DEBUG_MU = localLOGV || false;
254    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255    static final boolean DEBUG_LRU = localLOGV || false;
256    static final boolean DEBUG_PAUSE = localLOGV || false;
257    static final boolean DEBUG_POWER = localLOGV || false;
258    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260    static final boolean DEBUG_PROCESSES = localLOGV || false;
261    static final boolean DEBUG_PROVIDER = localLOGV || false;
262    static final boolean DEBUG_RESULTS = localLOGV || false;
263    static final boolean DEBUG_SERVICE = localLOGV || false;
264    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265    static final boolean DEBUG_STACK = localLOGV || false;
266    static final boolean DEBUG_SWITCH = localLOGV || false;
267    static final boolean DEBUG_TASKS = localLOGV || false;
268    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269    static final boolean DEBUG_TRANSITION = localLOGV || false;
270    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272    static final boolean DEBUG_VISBILITY = localLOGV || false;
273    static final boolean DEBUG_PSS = localLOGV || false;
274    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275    static final boolean DEBUG_RECENTS = localLOGV || false;
276    static final boolean VALIDATE_TOKENS = false;
277    static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279    // Control over CPU and battery monitoring.
280    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281    static final boolean MONITOR_CPU_USAGE = true;
282    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284    static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286    // The flags that are set for all calls we make to the package manager.
287    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293    // Maximum number recent bitmaps to keep in memory.
294    static final int MAX_RECENT_BITMAPS = 5;
295
296    // Amount of time after a call to stopAppSwitches() during which we will
297    // prevent further untrusted switches from happening.
298    static final long APP_SWITCH_DELAY_TIME = 5*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real.
302    static final int PROC_START_TIMEOUT = 10*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real, when the process was
306    // started with a wrapper for instrumentation (such as Valgrind) because it
307    // could take much longer than usual.
308    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310    // How long to wait after going idle before forcing apps to GC.
311    static final int GC_TIMEOUT = 5*1000;
312
313    // The minimum amount of time between successive GC requests for a process.
314    static final int GC_MIN_INTERVAL = 60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process.
317    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process
320    // when the request is due to the memory state being lowered.
321    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323    // The rate at which we check for apps using excessive power -- 15 mins.
324    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on wake locks to start killing things.
328    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on CPU usage to start killing things.
332    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // How long we allow a receiver to run before giving up on it.
335    static final int BROADCAST_FG_TIMEOUT = 10*1000;
336    static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338    // How long we wait until we timeout on key dispatching.
339    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341    // How long we wait until we timeout on key dispatching during instrumentation.
342    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344    // Amount of time we wait for observers to handle a user switch before
345    // giving up on them and unfreezing the screen.
346    static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348    // Maximum number of users we allow to be running at a time.
349    static final int MAX_RUNNING_USERS = 3;
350
351    // How long to wait in getAssistContextExtras for the activity and foreground services
352    // to respond with the result.
353    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355    // Maximum number of persisted Uri grants a package is allowed
356    static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358    static final int MY_PID = Process.myPid();
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    // How many bytes to write into the dropbox log before truncating
363    static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365    // Access modes for handleIncomingUser.
366    static final int ALLOW_NON_FULL = 0;
367    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368    static final int ALLOW_FULL_ONLY = 2;
369
370    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372    /** All system services */
373    SystemServiceManager mSystemServiceManager;
374
375    private Installer mInstaller;
376
377    /** Run all ActivityStacks through this */
378    ActivityStackSupervisor mStackSupervisor;
379
380    public IntentFirewall mIntentFirewall;
381
382    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
383    // default actuion automatically.  Important for devices without direct input
384    // devices.
385    private boolean mShowDialogs = true;
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
423
424    /**
425     * For addAppTask: cached of the last activity component that was added.
426     */
427    ComponentName mLastAddedTaskComponent;
428
429    /**
430     * For addAppTask: cached of the last activity uid that was added.
431     */
432    int mLastAddedTaskUid;
433
434    /**
435     * For addAppTask: cached of the last ActivityInfo that was added.
436     */
437    ActivityInfo mLastAddedTaskActivity;
438
439    public class PendingAssistExtras extends Binder implements Runnable {
440        public final ActivityRecord activity;
441        public final Bundle extras;
442        public final Intent intent;
443        public final String hint;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            userHandle = _userHandle;
454        }
455        @Override
456        public void run() {
457            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
458            synchronized (this) {
459                haveResult = true;
460                notifyAll();
461            }
462        }
463    }
464
465    final ArrayList<PendingAssistExtras> mPendingAssistExtras
466            = new ArrayList<PendingAssistExtras>();
467
468    /**
469     * Process management.
470     */
471    final ProcessList mProcessList = new ProcessList();
472
473    /**
474     * All of the applications we currently have running organized by name.
475     * The keys are strings of the application package name (as
476     * returned by the package manager), and the keys are ApplicationRecord
477     * objects.
478     */
479    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
480
481    /**
482     * Tracking long-term execution of processes to look for abuse and other
483     * bad app behavior.
484     */
485    final ProcessStatsService mProcessStats;
486
487    /**
488     * The currently running isolated processes.
489     */
490    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
491
492    /**
493     * Counter for assigning isolated process uids, to avoid frequently reusing the
494     * same ones.
495     */
496    int mNextIsolatedProcessUid = 0;
497
498    /**
499     * The currently running heavy-weight process, if any.
500     */
501    ProcessRecord mHeavyWeightProcess = null;
502
503    /**
504     * The last time that various processes have crashed.
505     */
506    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
507
508    /**
509     * Information about a process that is currently marked as bad.
510     */
511    static final class BadProcessInfo {
512        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
513            this.time = time;
514            this.shortMsg = shortMsg;
515            this.longMsg = longMsg;
516            this.stack = stack;
517        }
518
519        final long time;
520        final String shortMsg;
521        final String longMsg;
522        final String stack;
523    }
524
525    /**
526     * Set of applications that we consider to be bad, and will reject
527     * incoming broadcasts from (which the user has no control over).
528     * Processes are added to this set when they have crashed twice within
529     * a minimum amount of time; they are removed from it when they are
530     * later restarted (hopefully due to some user action).  The value is the
531     * time it was added to the list.
532     */
533    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
534
535    /**
536     * All of the processes we currently have running organized by pid.
537     * The keys are the pid running the application.
538     *
539     * <p>NOTE: This object is protected by its own lock, NOT the global
540     * activity manager lock!
541     */
542    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
543
544    /**
545     * All of the processes that have been forced to be foreground.  The key
546     * is the pid of the caller who requested it (we hold a death
547     * link on it).
548     */
549    abstract class ForegroundToken implements IBinder.DeathRecipient {
550        int pid;
551        IBinder token;
552    }
553    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
554
555    /**
556     * List of records for processes that someone had tried to start before the
557     * system was ready.  We don't start them at that point, but ensure they
558     * are started by the time booting is complete.
559     */
560    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
561
562    /**
563     * List of persistent applications that are in the process
564     * of being started.
565     */
566    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
567
568    /**
569     * Processes that are being forcibly torn down.
570     */
571    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of running applications, sorted by recent usage.
575     * The first entry in the list is the least recently used.
576     */
577    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * Where in mLruProcesses that the processes hosting activities start.
581     */
582    int mLruProcessActivityStart = 0;
583
584    /**
585     * Where in mLruProcesses that the processes hosting services start.
586     * This is after (lower index) than mLruProcessesActivityStart.
587     */
588    int mLruProcessServiceStart = 0;
589
590    /**
591     * List of processes that should gc as soon as things are idle.
592     */
593    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
594
595    /**
596     * Processes we want to collect PSS data from.
597     */
598    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
599
600    /**
601     * Last time we requested PSS data of all processes.
602     */
603    long mLastFullPssTime = SystemClock.uptimeMillis();
604
605    /**
606     * If set, the next time we collect PSS data we should do a full collection
607     * with data from native processes and the kernel.
608     */
609    boolean mFullPssPending = false;
610
611    /**
612     * This is the process holding what we currently consider to be
613     * the "home" activity.
614     */
615    ProcessRecord mHomeProcess;
616
617    /**
618     * This is the process holding the activity the user last visited that
619     * is in a different process from the one they are currently in.
620     */
621    ProcessRecord mPreviousProcess;
622
623    /**
624     * The time at which the previous process was last visible.
625     */
626    long mPreviousProcessVisibleTime;
627
628    /**
629     * Which uses have been started, so are allowed to run code.
630     */
631    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
632
633    /**
634     * LRU list of history of current users.  Most recently current is at the end.
635     */
636    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
637
638    /**
639     * Constant array of the users that are currently started.
640     */
641    int[] mStartedUserArray = new int[] { 0 };
642
643    /**
644     * Registered observers of the user switching mechanics.
645     */
646    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
647            = new RemoteCallbackList<IUserSwitchObserver>();
648
649    /**
650     * Currently active user switch.
651     */
652    Object mCurUserSwitchCallback;
653
654    /**
655     * Packages that the user has asked to have run in screen size
656     * compatibility mode instead of filling the screen.
657     */
658    final CompatModePackages mCompatModePackages;
659
660    /**
661     * Set of IntentSenderRecord objects that are currently active.
662     */
663    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
664            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
665
666    /**
667     * Fingerprints (hashCode()) of stack traces that we've
668     * already logged DropBox entries for.  Guarded by itself.  If
669     * something (rogue user app) forces this over
670     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
671     */
672    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
673    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
674
675    /**
676     * Strict Mode background batched logging state.
677     *
678     * The string buffer is guarded by itself, and its lock is also
679     * used to determine if another batched write is already
680     * in-flight.
681     */
682    private final StringBuilder mStrictModeBuffer = new StringBuilder();
683
684    /**
685     * Keeps track of all IIntentReceivers that have been registered for
686     * broadcasts.  Hash keys are the receiver IBinder, hash value is
687     * a ReceiverList.
688     */
689    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
690            new HashMap<IBinder, ReceiverList>();
691
692    /**
693     * Resolver for broadcast intents to registered receivers.
694     * Holds BroadcastFilter (subclass of IntentFilter).
695     */
696    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
697            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
698        @Override
699        protected boolean allowFilterResult(
700                BroadcastFilter filter, List<BroadcastFilter> dest) {
701            IBinder target = filter.receiverList.receiver.asBinder();
702            for (int i=dest.size()-1; i>=0; i--) {
703                if (dest.get(i).receiverList.receiver.asBinder() == target) {
704                    return false;
705                }
706            }
707            return true;
708        }
709
710        @Override
711        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
712            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
713                    || userId == filter.owningUserId) {
714                return super.newResult(filter, match, userId);
715            }
716            return null;
717        }
718
719        @Override
720        protected BroadcastFilter[] newArray(int size) {
721            return new BroadcastFilter[size];
722        }
723
724        @Override
725        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
726            return packageName.equals(filter.packageName);
727        }
728    };
729
730    /**
731     * State of all active sticky broadcasts per user.  Keys are the action of the
732     * sticky Intent, values are an ArrayList of all broadcasted intents with
733     * that action (which should usually be one).  The SparseArray is keyed
734     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
735     * for stickies that are sent to all users.
736     */
737    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
738            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
739
740    final ActiveServices mServices;
741
742    /**
743     * Backup/restore process management
744     */
745    String mBackupAppName = null;
746    BackupRecord mBackupTarget = null;
747
748    final ProviderMap mProviderMap;
749
750    /**
751     * List of content providers who have clients waiting for them.  The
752     * application is currently being launched and the provider will be
753     * removed from this list once it is published.
754     */
755    final ArrayList<ContentProviderRecord> mLaunchingProviders
756            = new ArrayList<ContentProviderRecord>();
757
758    /**
759     * File storing persisted {@link #mGrantedUriPermissions}.
760     */
761    private final AtomicFile mGrantFile;
762
763    /** XML constants used in {@link #mGrantFile} */
764    private static final String TAG_URI_GRANTS = "uri-grants";
765    private static final String TAG_URI_GRANT = "uri-grant";
766    private static final String ATTR_USER_HANDLE = "userHandle";
767    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
768    private static final String ATTR_TARGET_USER_ID = "targetUserId";
769    private static final String ATTR_SOURCE_PKG = "sourcePkg";
770    private static final String ATTR_TARGET_PKG = "targetPkg";
771    private static final String ATTR_URI = "uri";
772    private static final String ATTR_MODE_FLAGS = "modeFlags";
773    private static final String ATTR_CREATED_TIME = "createdTime";
774    private static final String ATTR_PREFIX = "prefix";
775
776    /**
777     * Global set of specific {@link Uri} permissions that have been granted.
778     * This optimized lookup structure maps from {@link UriPermission#targetUid}
779     * to {@link UriPermission#uri} to {@link UriPermission}.
780     */
781    @GuardedBy("this")
782    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
783            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
784
785    public static class GrantUri {
786        public final int sourceUserId;
787        public final Uri uri;
788        public boolean prefix;
789
790        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
791            this.sourceUserId = sourceUserId;
792            this.uri = uri;
793            this.prefix = prefix;
794        }
795
796        @Override
797        public int hashCode() {
798            int hashCode = 1;
799            hashCode = 31 * hashCode + sourceUserId;
800            hashCode = 31 * hashCode + uri.hashCode();
801            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
802            return hashCode;
803        }
804
805        @Override
806        public boolean equals(Object o) {
807            if (o instanceof GrantUri) {
808                GrantUri other = (GrantUri) o;
809                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
810                        && prefix == other.prefix;
811            }
812            return false;
813        }
814
815        @Override
816        public String toString() {
817            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
818            if (prefix) result += " [prefix]";
819            return result;
820        }
821
822        public String toSafeString() {
823            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
824            if (prefix) result += " [prefix]";
825            return result;
826        }
827
828        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
829            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
830                    ContentProvider.getUriWithoutUserId(uri), false);
831        }
832    }
833
834    CoreSettingsObserver mCoreSettingsObserver;
835
836    /**
837     * Thread-local storage used to carry caller permissions over through
838     * indirect content-provider access.
839     */
840    private class Identity {
841        public final IBinder token;
842        public final int pid;
843        public final int uid;
844
845        Identity(IBinder _token, int _pid, int _uid) {
846            token = _token;
847            pid = _pid;
848            uid = _uid;
849        }
850    }
851
852    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
853
854    /**
855     * All information we have collected about the runtime performance of
856     * any user id that can impact battery performance.
857     */
858    final BatteryStatsService mBatteryStatsService;
859
860    /**
861     * Information about component usage
862     */
863    UsageStatsManagerInternal mUsageStatsService;
864
865    /**
866     * Information about and control over application operations
867     */
868    final AppOpsService mAppOpsService;
869
870    /**
871     * Save recent tasks information across reboots.
872     */
873    final TaskPersister mTaskPersister;
874
875    /**
876     * Current configuration information.  HistoryRecord objects are given
877     * a reference to this object to indicate which configuration they are
878     * currently running in, so this object must be kept immutable.
879     */
880    Configuration mConfiguration = new Configuration();
881
882    /**
883     * Current sequencing integer of the configuration, for skipping old
884     * configurations.
885     */
886    int mConfigurationSeq = 0;
887
888    /**
889     * Hardware-reported OpenGLES version.
890     */
891    final int GL_ES_VERSION;
892
893    /**
894     * List of initialization arguments to pass to all processes when binding applications to them.
895     * For example, references to the commonly used services.
896     */
897    HashMap<String, IBinder> mAppBindArgs;
898
899    /**
900     * Temporary to avoid allocations.  Protected by main lock.
901     */
902    final StringBuilder mStringBuilder = new StringBuilder(256);
903
904    /**
905     * Used to control how we initialize the service.
906     */
907    ComponentName mTopComponent;
908    String mTopAction = Intent.ACTION_MAIN;
909    String mTopData;
910    boolean mProcessesReady = false;
911    boolean mSystemReady = false;
912    boolean mBooting = false;
913    boolean mCallFinishBooting = false;
914    boolean mBootAnimationComplete = false;
915    boolean mWaitingUpdate = false;
916    boolean mDidUpdate = false;
917    boolean mOnBattery = false;
918    boolean mLaunchWarningShown = false;
919
920    Context mContext;
921
922    int mFactoryTest;
923
924    boolean mCheckedForSetup;
925
926    /**
927     * The time at which we will allow normal application switches again,
928     * after a call to {@link #stopAppSwitches()}.
929     */
930    long mAppSwitchesAllowedTime;
931
932    /**
933     * This is set to true after the first switch after mAppSwitchesAllowedTime
934     * is set; any switches after that will clear the time.
935     */
936    boolean mDidAppSwitch;
937
938    /**
939     * Last time (in realtime) at which we checked for power usage.
940     */
941    long mLastPowerCheckRealtime;
942
943    /**
944     * Last time (in uptime) at which we checked for power usage.
945     */
946    long mLastPowerCheckUptime;
947
948    /**
949     * Set while we are wanting to sleep, to prevent any
950     * activities from being started/resumed.
951     */
952    private boolean mSleeping = false;
953
954    /**
955     * Set while we are running a voice interaction.  This overrides
956     * sleeping while it is active.
957     */
958    private boolean mRunningVoice = false;
959
960    /**
961     * State of external calls telling us if the device is asleep.
962     */
963    private boolean mWentToSleep = false;
964
965    static final int LOCK_SCREEN_HIDDEN = 0;
966    static final int LOCK_SCREEN_LEAVING = 1;
967    static final int LOCK_SCREEN_SHOWN = 2;
968    /**
969     * State of external call telling us if the lock screen is shown.
970     */
971    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
972
973    /**
974     * Set if we are shutting down the system, similar to sleeping.
975     */
976    boolean mShuttingDown = false;
977
978    /**
979     * Current sequence id for oom_adj computation traversal.
980     */
981    int mAdjSeq = 0;
982
983    /**
984     * Current sequence id for process LRU updating.
985     */
986    int mLruSeq = 0;
987
988    /**
989     * Keep track of the non-cached/empty process we last found, to help
990     * determine how to distribute cached/empty processes next time.
991     */
992    int mNumNonCachedProcs = 0;
993
994    /**
995     * Keep track of the number of cached hidden procs, to balance oom adj
996     * distribution between those and empty procs.
997     */
998    int mNumCachedHiddenProcs = 0;
999
1000    /**
1001     * Keep track of the number of service processes we last found, to
1002     * determine on the next iteration which should be B services.
1003     */
1004    int mNumServiceProcs = 0;
1005    int mNewNumAServiceProcs = 0;
1006    int mNewNumServiceProcs = 0;
1007
1008    /**
1009     * Allow the current computed overall memory level of the system to go down?
1010     * This is set to false when we are killing processes for reasons other than
1011     * memory management, so that the now smaller process list will not be taken as
1012     * an indication that memory is tighter.
1013     */
1014    boolean mAllowLowerMemLevel = false;
1015
1016    /**
1017     * The last computed memory level, for holding when we are in a state that
1018     * processes are going away for other reasons.
1019     */
1020    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1021
1022    /**
1023     * The last total number of process we have, to determine if changes actually look
1024     * like a shrinking number of process due to lower RAM.
1025     */
1026    int mLastNumProcesses;
1027
1028    /**
1029     * The uptime of the last time we performed idle maintenance.
1030     */
1031    long mLastIdleTime = SystemClock.uptimeMillis();
1032
1033    /**
1034     * Total time spent with RAM that has been added in the past since the last idle time.
1035     */
1036    long mLowRamTimeSinceLastIdle = 0;
1037
1038    /**
1039     * If RAM is currently low, when that horrible situation started.
1040     */
1041    long mLowRamStartTime = 0;
1042
1043    /**
1044     * For reporting to battery stats the current top application.
1045     */
1046    private String mCurResumedPackage = null;
1047    private int mCurResumedUid = -1;
1048
1049    /**
1050     * For reporting to battery stats the apps currently running foreground
1051     * service.  The ProcessMap is package/uid tuples; each of these contain
1052     * an array of the currently foreground processes.
1053     */
1054    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1055            = new ProcessMap<ArrayList<ProcessRecord>>();
1056
1057    /**
1058     * This is set if we had to do a delayed dexopt of an app before launching
1059     * it, to increase the ANR timeouts in that case.
1060     */
1061    boolean mDidDexOpt;
1062
1063    /**
1064     * Set if the systemServer made a call to enterSafeMode.
1065     */
1066    boolean mSafeMode;
1067
1068    String mDebugApp = null;
1069    boolean mWaitForDebugger = false;
1070    boolean mDebugTransient = false;
1071    String mOrigDebugApp = null;
1072    boolean mOrigWaitForDebugger = false;
1073    boolean mAlwaysFinishActivities = false;
1074    IActivityController mController = null;
1075    String mProfileApp = null;
1076    ProcessRecord mProfileProc = null;
1077    String mProfileFile;
1078    ParcelFileDescriptor mProfileFd;
1079    int mSamplingInterval = 0;
1080    boolean mAutoStopProfiler = false;
1081    int mProfileType = 0;
1082    String mOpenGlTraceApp = null;
1083
1084    static class ProcessChangeItem {
1085        static final int CHANGE_ACTIVITIES = 1<<0;
1086        static final int CHANGE_PROCESS_STATE = 1<<1;
1087        int changes;
1088        int uid;
1089        int pid;
1090        int processState;
1091        boolean foregroundActivities;
1092    }
1093
1094    final RemoteCallbackList<IProcessObserver> mProcessObservers
1095            = new RemoteCallbackList<IProcessObserver>();
1096    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1097
1098    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1099            = new ArrayList<ProcessChangeItem>();
1100    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1101            = new ArrayList<ProcessChangeItem>();
1102
1103    /**
1104     * Runtime CPU use collection thread.  This object's lock is used to
1105     * perform synchronization with the thread (notifying it to run).
1106     */
1107    final Thread mProcessCpuThread;
1108
1109    /**
1110     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1111     * Must acquire this object's lock when accessing it.
1112     * NOTE: this lock will be held while doing long operations (trawling
1113     * through all processes in /proc), so it should never be acquired by
1114     * any critical paths such as when holding the main activity manager lock.
1115     */
1116    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1117            MONITOR_THREAD_CPU_USAGE);
1118    final AtomicLong mLastCpuTime = new AtomicLong(0);
1119    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1120
1121    long mLastWriteTime = 0;
1122
1123    /**
1124     * Used to retain an update lock when the foreground activity is in
1125     * immersive mode.
1126     */
1127    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1128
1129    /**
1130     * Set to true after the system has finished booting.
1131     */
1132    boolean mBooted = false;
1133
1134    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1135    int mProcessLimitOverride = -1;
1136
1137    WindowManagerService mWindowManager;
1138
1139    final ActivityThread mSystemThread;
1140
1141    // Holds the current foreground user's id
1142    int mCurrentUserId = 0;
1143    // Holds the target user's id during a user switch
1144    int mTargetUserId = UserHandle.USER_NULL;
1145    // If there are multiple profiles for the current user, their ids are here
1146    // Currently only the primary user can have managed profiles
1147    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1148
1149    /**
1150     * Mapping from each known user ID to the profile group ID it is associated with.
1151     */
1152    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1153
1154    private UserManagerService mUserManager;
1155
1156    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1157        final ProcessRecord mApp;
1158        final int mPid;
1159        final IApplicationThread mAppThread;
1160
1161        AppDeathRecipient(ProcessRecord app, int pid,
1162                IApplicationThread thread) {
1163            if (localLOGV) Slog.v(
1164                TAG, "New death recipient " + this
1165                + " for thread " + thread.asBinder());
1166            mApp = app;
1167            mPid = pid;
1168            mAppThread = thread;
1169        }
1170
1171        @Override
1172        public void binderDied() {
1173            if (localLOGV) Slog.v(
1174                TAG, "Death received in " + this
1175                + " for thread " + mAppThread.asBinder());
1176            synchronized(ActivityManagerService.this) {
1177                appDiedLocked(mApp, mPid, mAppThread);
1178            }
1179        }
1180    }
1181
1182    static final int SHOW_ERROR_MSG = 1;
1183    static final int SHOW_NOT_RESPONDING_MSG = 2;
1184    static final int SHOW_FACTORY_ERROR_MSG = 3;
1185    static final int UPDATE_CONFIGURATION_MSG = 4;
1186    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1187    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1188    static final int SERVICE_TIMEOUT_MSG = 12;
1189    static final int UPDATE_TIME_ZONE = 13;
1190    static final int SHOW_UID_ERROR_MSG = 14;
1191    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1192    static final int PROC_START_TIMEOUT_MSG = 20;
1193    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1194    static final int KILL_APPLICATION_MSG = 22;
1195    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1196    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1197    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1198    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1199    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1200    static final int CLEAR_DNS_CACHE_MSG = 28;
1201    static final int UPDATE_HTTP_PROXY_MSG = 29;
1202    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1203    static final int DISPATCH_PROCESSES_CHANGED = 31;
1204    static final int DISPATCH_PROCESS_DIED = 32;
1205    static final int REPORT_MEM_USAGE_MSG = 33;
1206    static final int REPORT_USER_SWITCH_MSG = 34;
1207    static final int CONTINUE_USER_SWITCH_MSG = 35;
1208    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1209    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1210    static final int PERSIST_URI_GRANTS_MSG = 38;
1211    static final int REQUEST_ALL_PSS_MSG = 39;
1212    static final int START_PROFILES_MSG = 40;
1213    static final int UPDATE_TIME = 41;
1214    static final int SYSTEM_USER_START_MSG = 42;
1215    static final int SYSTEM_USER_CURRENT_MSG = 43;
1216    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1217    static final int FINISH_BOOTING_MSG = 45;
1218    static final int START_USER_SWITCH_MSG = 46;
1219    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1220    static final int DISMISS_DIALOG_MSG = 48;
1221
1222    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1223    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1224    static final int FIRST_COMPAT_MODE_MSG = 300;
1225    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1226
1227    CompatModeDialog mCompatModeDialog;
1228    long mLastMemUsageReportTime = 0;
1229
1230    /**
1231     * Flag whether the current user is a "monkey", i.e. whether
1232     * the UI is driven by a UI automation tool.
1233     */
1234    private boolean mUserIsMonkey;
1235
1236    /** Flag whether the device has a Recents UI */
1237    boolean mHasRecents;
1238
1239    /** The dimensions of the thumbnails in the Recents UI. */
1240    int mThumbnailWidth;
1241    int mThumbnailHeight;
1242
1243    final ServiceThread mHandlerThread;
1244    final MainHandler mHandler;
1245
1246    final class MainHandler extends Handler {
1247        public MainHandler(Looper looper) {
1248            super(looper, null, true);
1249        }
1250
1251        @Override
1252        public void handleMessage(Message msg) {
1253            switch (msg.what) {
1254            case SHOW_ERROR_MSG: {
1255                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1256                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1257                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1258                synchronized (ActivityManagerService.this) {
1259                    ProcessRecord proc = (ProcessRecord)data.get("app");
1260                    AppErrorResult res = (AppErrorResult) data.get("result");
1261                    if (proc != null && proc.crashDialog != null) {
1262                        Slog.e(TAG, "App already has crash dialog: " + proc);
1263                        if (res != null) {
1264                            res.set(0);
1265                        }
1266                        return;
1267                    }
1268                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1269                            >= Process.FIRST_APPLICATION_UID
1270                            && proc.pid != MY_PID);
1271                    for (int userId : mCurrentProfileIds) {
1272                        isBackground &= (proc.userId != userId);
1273                    }
1274                    if (isBackground && !showBackground) {
1275                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1276                        if (res != null) {
1277                            res.set(0);
1278                        }
1279                        return;
1280                    }
1281                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1282                        Dialog d = new AppErrorDialog(mContext,
1283                                ActivityManagerService.this, res, proc);
1284                        d.show();
1285                        proc.crashDialog = d;
1286                    } else {
1287                        // The device is asleep, so just pretend that the user
1288                        // saw a crash dialog and hit "force quit".
1289                        if (res != null) {
1290                            res.set(0);
1291                        }
1292                    }
1293                }
1294
1295                ensureBootCompleted();
1296            } break;
1297            case SHOW_NOT_RESPONDING_MSG: {
1298                synchronized (ActivityManagerService.this) {
1299                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1300                    ProcessRecord proc = (ProcessRecord)data.get("app");
1301                    if (proc != null && proc.anrDialog != null) {
1302                        Slog.e(TAG, "App already has anr dialog: " + proc);
1303                        return;
1304                    }
1305
1306                    Intent intent = new Intent("android.intent.action.ANR");
1307                    if (!mProcessesReady) {
1308                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1309                                | Intent.FLAG_RECEIVER_FOREGROUND);
1310                    }
1311                    broadcastIntentLocked(null, null, intent,
1312                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1313                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1314
1315                    if (mShowDialogs) {
1316                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1317                                mContext, proc, (ActivityRecord)data.get("activity"),
1318                                msg.arg1 != 0);
1319                        d.show();
1320                        proc.anrDialog = d;
1321                    } else {
1322                        // Just kill the app if there is no dialog to be shown.
1323                        killAppAtUsersRequest(proc, null);
1324                    }
1325                }
1326
1327                ensureBootCompleted();
1328            } break;
1329            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1330                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1331                synchronized (ActivityManagerService.this) {
1332                    ProcessRecord proc = (ProcessRecord) data.get("app");
1333                    if (proc == null) {
1334                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1335                        break;
1336                    }
1337                    if (proc.crashDialog != null) {
1338                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1339                        return;
1340                    }
1341                    AppErrorResult res = (AppErrorResult) data.get("result");
1342                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1343                        Dialog d = new StrictModeViolationDialog(mContext,
1344                                ActivityManagerService.this, res, proc);
1345                        d.show();
1346                        proc.crashDialog = d;
1347                    } else {
1348                        // The device is asleep, so just pretend that the user
1349                        // saw a crash dialog and hit "force quit".
1350                        res.set(0);
1351                    }
1352                }
1353                ensureBootCompleted();
1354            } break;
1355            case SHOW_FACTORY_ERROR_MSG: {
1356                Dialog d = new FactoryErrorDialog(
1357                    mContext, msg.getData().getCharSequence("msg"));
1358                d.show();
1359                ensureBootCompleted();
1360            } break;
1361            case UPDATE_CONFIGURATION_MSG: {
1362                final ContentResolver resolver = mContext.getContentResolver();
1363                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1364            } break;
1365            case GC_BACKGROUND_PROCESSES_MSG: {
1366                synchronized (ActivityManagerService.this) {
1367                    performAppGcsIfAppropriateLocked();
1368                }
1369            } break;
1370            case WAIT_FOR_DEBUGGER_MSG: {
1371                synchronized (ActivityManagerService.this) {
1372                    ProcessRecord app = (ProcessRecord)msg.obj;
1373                    if (msg.arg1 != 0) {
1374                        if (!app.waitedForDebugger) {
1375                            Dialog d = new AppWaitingForDebuggerDialog(
1376                                    ActivityManagerService.this,
1377                                    mContext, app);
1378                            app.waitDialog = d;
1379                            app.waitedForDebugger = true;
1380                            d.show();
1381                        }
1382                    } else {
1383                        if (app.waitDialog != null) {
1384                            app.waitDialog.dismiss();
1385                            app.waitDialog = null;
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SERVICE_TIMEOUT_MSG: {
1391                if (mDidDexOpt) {
1392                    mDidDexOpt = false;
1393                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1394                    nmsg.obj = msg.obj;
1395                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1396                    return;
1397                }
1398                mServices.serviceTimeout((ProcessRecord)msg.obj);
1399            } break;
1400            case UPDATE_TIME_ZONE: {
1401                synchronized (ActivityManagerService.this) {
1402                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1403                        ProcessRecord r = mLruProcesses.get(i);
1404                        if (r.thread != null) {
1405                            try {
1406                                r.thread.updateTimeZone();
1407                            } catch (RemoteException ex) {
1408                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1409                            }
1410                        }
1411                    }
1412                }
1413            } break;
1414            case CLEAR_DNS_CACHE_MSG: {
1415                synchronized (ActivityManagerService.this) {
1416                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1417                        ProcessRecord r = mLruProcesses.get(i);
1418                        if (r.thread != null) {
1419                            try {
1420                                r.thread.clearDnsCache();
1421                            } catch (RemoteException ex) {
1422                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1423                            }
1424                        }
1425                    }
1426                }
1427            } break;
1428            case UPDATE_HTTP_PROXY_MSG: {
1429                ProxyInfo proxy = (ProxyInfo)msg.obj;
1430                String host = "";
1431                String port = "";
1432                String exclList = "";
1433                Uri pacFileUrl = Uri.EMPTY;
1434                if (proxy != null) {
1435                    host = proxy.getHost();
1436                    port = Integer.toString(proxy.getPort());
1437                    exclList = proxy.getExclusionListAsString();
1438                    pacFileUrl = proxy.getPacFileUrl();
1439                }
1440                synchronized (ActivityManagerService.this) {
1441                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1442                        ProcessRecord r = mLruProcesses.get(i);
1443                        if (r.thread != null) {
1444                            try {
1445                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1446                            } catch (RemoteException ex) {
1447                                Slog.w(TAG, "Failed to update http proxy for: " +
1448                                        r.info.processName);
1449                            }
1450                        }
1451                    }
1452                }
1453            } break;
1454            case SHOW_UID_ERROR_MSG: {
1455                if (mShowDialogs) {
1456                    AlertDialog d = new BaseErrorDialog(mContext);
1457                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1458                    d.setCancelable(false);
1459                    d.setTitle(mContext.getText(R.string.android_system_label));
1460                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1461                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1462                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1463                    d.show();
1464                }
1465            } break;
1466            case SHOW_FINGERPRINT_ERROR_MSG: {
1467                if (mShowDialogs) {
1468                    AlertDialog d = new BaseErrorDialog(mContext);
1469                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1470                    d.setCancelable(false);
1471                    d.setTitle(mContext.getText(R.string.android_system_label));
1472                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1473                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1474                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1475                    d.show();
1476                }
1477            } break;
1478            case PROC_START_TIMEOUT_MSG: {
1479                if (mDidDexOpt) {
1480                    mDidDexOpt = false;
1481                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1482                    nmsg.obj = msg.obj;
1483                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1484                    return;
1485                }
1486                ProcessRecord app = (ProcessRecord)msg.obj;
1487                synchronized (ActivityManagerService.this) {
1488                    processStartTimedOutLocked(app);
1489                }
1490            } break;
1491            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1492                synchronized (ActivityManagerService.this) {
1493                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1494                }
1495            } break;
1496            case KILL_APPLICATION_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    int appid = msg.arg1;
1499                    boolean restart = (msg.arg2 == 1);
1500                    Bundle bundle = (Bundle)msg.obj;
1501                    String pkg = bundle.getString("pkg");
1502                    String reason = bundle.getString("reason");
1503                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1504                            false, UserHandle.USER_ALL, reason);
1505                }
1506            } break;
1507            case FINALIZE_PENDING_INTENT_MSG: {
1508                ((PendingIntentRecord)msg.obj).completeFinalize();
1509            } break;
1510            case POST_HEAVY_NOTIFICATION_MSG: {
1511                INotificationManager inm = NotificationManager.getService();
1512                if (inm == null) {
1513                    return;
1514                }
1515
1516                ActivityRecord root = (ActivityRecord)msg.obj;
1517                ProcessRecord process = root.app;
1518                if (process == null) {
1519                    return;
1520                }
1521
1522                try {
1523                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1524                    String text = mContext.getString(R.string.heavy_weight_notification,
1525                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1526                    Notification notification = new Notification();
1527                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1528                    notification.when = 0;
1529                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1530                    notification.tickerText = text;
1531                    notification.defaults = 0; // please be quiet
1532                    notification.sound = null;
1533                    notification.vibrate = null;
1534                    notification.color = mContext.getResources().getColor(
1535                            com.android.internal.R.color.system_notification_accent_color);
1536                    notification.setLatestEventInfo(context, text,
1537                            mContext.getText(R.string.heavy_weight_notification_detail),
1538                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1539                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1540                                    new UserHandle(root.userId)));
1541
1542                    try {
1543                        int[] outId = new int[1];
1544                        inm.enqueueNotificationWithTag("android", "android", null,
1545                                R.string.heavy_weight_notification,
1546                                notification, outId, root.userId);
1547                    } catch (RuntimeException e) {
1548                        Slog.w(ActivityManagerService.TAG,
1549                                "Error showing notification for heavy-weight app", e);
1550                    } catch (RemoteException e) {
1551                    }
1552                } catch (NameNotFoundException e) {
1553                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1554                }
1555            } break;
1556            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1557                INotificationManager inm = NotificationManager.getService();
1558                if (inm == null) {
1559                    return;
1560                }
1561                try {
1562                    inm.cancelNotificationWithTag("android", null,
1563                            R.string.heavy_weight_notification,  msg.arg1);
1564                } catch (RuntimeException e) {
1565                    Slog.w(ActivityManagerService.TAG,
1566                            "Error canceling notification for service", e);
1567                } catch (RemoteException e) {
1568                }
1569            } break;
1570            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1571                synchronized (ActivityManagerService.this) {
1572                    checkExcessivePowerUsageLocked(true);
1573                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1574                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1575                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1576                }
1577            } break;
1578            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1579                synchronized (ActivityManagerService.this) {
1580                    ActivityRecord ar = (ActivityRecord)msg.obj;
1581                    if (mCompatModeDialog != null) {
1582                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1583                                ar.info.applicationInfo.packageName)) {
1584                            return;
1585                        }
1586                        mCompatModeDialog.dismiss();
1587                        mCompatModeDialog = null;
1588                    }
1589                    if (ar != null && false) {
1590                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1591                                ar.packageName)) {
1592                            int mode = mCompatModePackages.computeCompatModeLocked(
1593                                    ar.info.applicationInfo);
1594                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1595                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1596                                mCompatModeDialog = new CompatModeDialog(
1597                                        ActivityManagerService.this, mContext,
1598                                        ar.info.applicationInfo);
1599                                mCompatModeDialog.show();
1600                            }
1601                        }
1602                    }
1603                }
1604                break;
1605            }
1606            case DISPATCH_PROCESSES_CHANGED: {
1607                dispatchProcessesChanged();
1608                break;
1609            }
1610            case DISPATCH_PROCESS_DIED: {
1611                final int pid = msg.arg1;
1612                final int uid = msg.arg2;
1613                dispatchProcessDied(pid, uid);
1614                break;
1615            }
1616            case REPORT_MEM_USAGE_MSG: {
1617                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1618                Thread thread = new Thread() {
1619                    @Override public void run() {
1620                        reportMemUsage(memInfos);
1621                    }
1622                };
1623                thread.start();
1624                break;
1625            }
1626            case START_USER_SWITCH_MSG: {
1627                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1628                break;
1629            }
1630            case REPORT_USER_SWITCH_MSG: {
1631                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1632                break;
1633            }
1634            case CONTINUE_USER_SWITCH_MSG: {
1635                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1636                break;
1637            }
1638            case USER_SWITCH_TIMEOUT_MSG: {
1639                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1640                break;
1641            }
1642            case IMMERSIVE_MODE_LOCK_MSG: {
1643                final boolean nextState = (msg.arg1 != 0);
1644                if (mUpdateLock.isHeld() != nextState) {
1645                    if (DEBUG_IMMERSIVE) {
1646                        final ActivityRecord r = (ActivityRecord) msg.obj;
1647                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1648                    }
1649                    if (nextState) {
1650                        mUpdateLock.acquire();
1651                    } else {
1652                        mUpdateLock.release();
1653                    }
1654                }
1655                break;
1656            }
1657            case PERSIST_URI_GRANTS_MSG: {
1658                writeGrantedUriPermissions();
1659                break;
1660            }
1661            case REQUEST_ALL_PSS_MSG: {
1662                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1663                break;
1664            }
1665            case START_PROFILES_MSG: {
1666                synchronized (ActivityManagerService.this) {
1667                    startProfilesLocked();
1668                }
1669                break;
1670            }
1671            case UPDATE_TIME: {
1672                synchronized (ActivityManagerService.this) {
1673                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1674                        ProcessRecord r = mLruProcesses.get(i);
1675                        if (r.thread != null) {
1676                            try {
1677                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1678                            } catch (RemoteException ex) {
1679                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1680                            }
1681                        }
1682                    }
1683                }
1684                break;
1685            }
1686            case SYSTEM_USER_START_MSG: {
1687                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1688                        Integer.toString(msg.arg1), msg.arg1);
1689                mSystemServiceManager.startUser(msg.arg1);
1690                break;
1691            }
1692            case SYSTEM_USER_CURRENT_MSG: {
1693                mBatteryStatsService.noteEvent(
1694                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1695                        Integer.toString(msg.arg2), msg.arg2);
1696                mBatteryStatsService.noteEvent(
1697                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1698                        Integer.toString(msg.arg1), msg.arg1);
1699                mSystemServiceManager.switchUser(msg.arg1);
1700                break;
1701            }
1702            case ENTER_ANIMATION_COMPLETE_MSG: {
1703                synchronized (ActivityManagerService.this) {
1704                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1705                    if (r != null && r.app != null && r.app.thread != null) {
1706                        try {
1707                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1708                        } catch (RemoteException e) {
1709                        }
1710                    }
1711                }
1712                break;
1713            }
1714            case FINISH_BOOTING_MSG: {
1715                if (msg.arg1 != 0) {
1716                    finishBooting();
1717                }
1718                if (msg.arg2 != 0) {
1719                    enableScreenAfterBoot();
1720                }
1721                break;
1722            }
1723            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1724                try {
1725                    Locale l = (Locale) msg.obj;
1726                    IBinder service = ServiceManager.getService("mount");
1727                    IMountService mountService = IMountService.Stub.asInterface(service);
1728                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1729                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1730                } catch (RemoteException e) {
1731                    Log.e(TAG, "Error storing locale for decryption UI", e);
1732                }
1733                break;
1734            }
1735            case DISMISS_DIALOG_MSG: {
1736                final Dialog d = (Dialog) msg.obj;
1737                d.dismiss();
1738                break;
1739            }
1740            }
1741        }
1742    };
1743
1744    static final int COLLECT_PSS_BG_MSG = 1;
1745
1746    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1747        @Override
1748        public void handleMessage(Message msg) {
1749            switch (msg.what) {
1750            case COLLECT_PSS_BG_MSG: {
1751                long start = SystemClock.uptimeMillis();
1752                MemInfoReader memInfo = null;
1753                synchronized (ActivityManagerService.this) {
1754                    if (mFullPssPending) {
1755                        mFullPssPending = false;
1756                        memInfo = new MemInfoReader();
1757                    }
1758                }
1759                if (memInfo != null) {
1760                    updateCpuStatsNow();
1761                    long nativeTotalPss = 0;
1762                    synchronized (mProcessCpuTracker) {
1763                        final int N = mProcessCpuTracker.countStats();
1764                        for (int j=0; j<N; j++) {
1765                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1766                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1767                                // This is definitely an application process; skip it.
1768                                continue;
1769                            }
1770                            synchronized (mPidsSelfLocked) {
1771                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1772                                    // This is one of our own processes; skip it.
1773                                    continue;
1774                                }
1775                            }
1776                            nativeTotalPss += Debug.getPss(st.pid, null);
1777                        }
1778                    }
1779                    memInfo.readMemInfo();
1780                    synchronized (ActivityManagerService.this) {
1781                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1782                                + (SystemClock.uptimeMillis()-start) + "ms");
1783                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1784                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1785                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1786                    }
1787                }
1788
1789                int i = 0;
1790                int num = 0;
1791                long[] tmp = new long[1];
1792                do {
1793                    ProcessRecord proc;
1794                    int procState;
1795                    int pid;
1796                    synchronized (ActivityManagerService.this) {
1797                        if (i >= mPendingPssProcesses.size()) {
1798                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1799                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1800                            mPendingPssProcesses.clear();
1801                            return;
1802                        }
1803                        proc = mPendingPssProcesses.get(i);
1804                        procState = proc.pssProcState;
1805                        if (proc.thread != null && procState == proc.setProcState) {
1806                            pid = proc.pid;
1807                        } else {
1808                            proc = null;
1809                            pid = 0;
1810                        }
1811                        i++;
1812                    }
1813                    if (proc != null) {
1814                        long pss = Debug.getPss(pid, tmp);
1815                        synchronized (ActivityManagerService.this) {
1816                            if (proc.thread != null && proc.setProcState == procState
1817                                    && proc.pid == pid) {
1818                                num++;
1819                                proc.lastPssTime = SystemClock.uptimeMillis();
1820                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1821                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1822                                        + ": " + pss + " lastPss=" + proc.lastPss
1823                                        + " state=" + ProcessList.makeProcStateString(procState));
1824                                if (proc.initialIdlePss == 0) {
1825                                    proc.initialIdlePss = pss;
1826                                }
1827                                proc.lastPss = pss;
1828                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1829                                    proc.lastCachedPss = pss;
1830                                }
1831                            }
1832                        }
1833                    }
1834                } while (true);
1835            }
1836            }
1837        }
1838    };
1839
1840    public void setSystemProcess() {
1841        try {
1842            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1843            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1844            ServiceManager.addService("meminfo", new MemBinder(this));
1845            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1846            ServiceManager.addService("dbinfo", new DbBinder(this));
1847            if (MONITOR_CPU_USAGE) {
1848                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1849            }
1850            ServiceManager.addService("permission", new PermissionController(this));
1851
1852            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1853                    "android", STOCK_PM_FLAGS);
1854            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1855
1856            synchronized (this) {
1857                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1858                app.persistent = true;
1859                app.pid = MY_PID;
1860                app.maxAdj = ProcessList.SYSTEM_ADJ;
1861                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1862                mProcessNames.put(app.processName, app.uid, app);
1863                synchronized (mPidsSelfLocked) {
1864                    mPidsSelfLocked.put(app.pid, app);
1865                }
1866                updateLruProcessLocked(app, false, null);
1867                updateOomAdjLocked();
1868            }
1869        } catch (PackageManager.NameNotFoundException e) {
1870            throw new RuntimeException(
1871                    "Unable to find android system package", e);
1872        }
1873    }
1874
1875    public void setWindowManager(WindowManagerService wm) {
1876        mWindowManager = wm;
1877        mStackSupervisor.setWindowManager(wm);
1878    }
1879
1880    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1881        mUsageStatsService = usageStatsManager;
1882    }
1883
1884    public void startObservingNativeCrashes() {
1885        final NativeCrashListener ncl = new NativeCrashListener(this);
1886        ncl.start();
1887    }
1888
1889    public IAppOpsService getAppOpsService() {
1890        return mAppOpsService;
1891    }
1892
1893    static class MemBinder extends Binder {
1894        ActivityManagerService mActivityManagerService;
1895        MemBinder(ActivityManagerService activityManagerService) {
1896            mActivityManagerService = activityManagerService;
1897        }
1898
1899        @Override
1900        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1901            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1902                    != PackageManager.PERMISSION_GRANTED) {
1903                pw.println("Permission Denial: can't dump meminfo from from pid="
1904                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1905                        + " without permission " + android.Manifest.permission.DUMP);
1906                return;
1907            }
1908
1909            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1910        }
1911    }
1912
1913    static class GraphicsBinder extends Binder {
1914        ActivityManagerService mActivityManagerService;
1915        GraphicsBinder(ActivityManagerService activityManagerService) {
1916            mActivityManagerService = activityManagerService;
1917        }
1918
1919        @Override
1920        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1921            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1922                    != PackageManager.PERMISSION_GRANTED) {
1923                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1924                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1925                        + " without permission " + android.Manifest.permission.DUMP);
1926                return;
1927            }
1928
1929            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1930        }
1931    }
1932
1933    static class DbBinder extends Binder {
1934        ActivityManagerService mActivityManagerService;
1935        DbBinder(ActivityManagerService activityManagerService) {
1936            mActivityManagerService = activityManagerService;
1937        }
1938
1939        @Override
1940        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1941            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1942                    != PackageManager.PERMISSION_GRANTED) {
1943                pw.println("Permission Denial: can't dump dbinfo from from pid="
1944                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1945                        + " without permission " + android.Manifest.permission.DUMP);
1946                return;
1947            }
1948
1949            mActivityManagerService.dumpDbInfo(fd, pw, args);
1950        }
1951    }
1952
1953    static class CpuBinder extends Binder {
1954        ActivityManagerService mActivityManagerService;
1955        CpuBinder(ActivityManagerService activityManagerService) {
1956            mActivityManagerService = activityManagerService;
1957        }
1958
1959        @Override
1960        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1961            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1962                    != PackageManager.PERMISSION_GRANTED) {
1963                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1964                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1965                        + " without permission " + android.Manifest.permission.DUMP);
1966                return;
1967            }
1968
1969            synchronized (mActivityManagerService.mProcessCpuTracker) {
1970                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1971                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1972                        SystemClock.uptimeMillis()));
1973            }
1974        }
1975    }
1976
1977    public static final class Lifecycle extends SystemService {
1978        private final ActivityManagerService mService;
1979
1980        public Lifecycle(Context context) {
1981            super(context);
1982            mService = new ActivityManagerService(context);
1983        }
1984
1985        @Override
1986        public void onStart() {
1987            mService.start();
1988        }
1989
1990        public ActivityManagerService getService() {
1991            return mService;
1992        }
1993    }
1994
1995    // Note: This method is invoked on the main thread but may need to attach various
1996    // handlers to other threads.  So take care to be explicit about the looper.
1997    public ActivityManagerService(Context systemContext) {
1998        mContext = systemContext;
1999        mFactoryTest = FactoryTest.getMode();
2000        mSystemThread = ActivityThread.currentActivityThread();
2001
2002        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2003
2004        mHandlerThread = new ServiceThread(TAG,
2005                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2006        mHandlerThread.start();
2007        mHandler = new MainHandler(mHandlerThread.getLooper());
2008
2009        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2010                "foreground", BROADCAST_FG_TIMEOUT, false);
2011        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2012                "background", BROADCAST_BG_TIMEOUT, true);
2013        mBroadcastQueues[0] = mFgBroadcastQueue;
2014        mBroadcastQueues[1] = mBgBroadcastQueue;
2015
2016        mServices = new ActiveServices(this);
2017        mProviderMap = new ProviderMap(this);
2018
2019        // TODO: Move creation of battery stats service outside of activity manager service.
2020        File dataDir = Environment.getDataDirectory();
2021        File systemDir = new File(dataDir, "system");
2022        systemDir.mkdirs();
2023        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2024        mBatteryStatsService.getActiveStatistics().readLocked();
2025        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2026        mOnBattery = DEBUG_POWER ? true
2027                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2028        mBatteryStatsService.getActiveStatistics().setCallback(this);
2029
2030        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2031
2032        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2033
2034        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2035
2036        // User 0 is the first and only user that runs at boot.
2037        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2038        mUserLru.add(Integer.valueOf(0));
2039        updateStartedUserArrayLocked();
2040
2041        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2042            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2043
2044        mConfiguration.setToDefaults();
2045        mConfiguration.setLocale(Locale.getDefault());
2046
2047        mConfigurationSeq = mConfiguration.seq = 1;
2048        mProcessCpuTracker.init();
2049
2050        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2051        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2052        mStackSupervisor = new ActivityStackSupervisor(this);
2053        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2054
2055        mProcessCpuThread = new Thread("CpuTracker") {
2056            @Override
2057            public void run() {
2058                while (true) {
2059                    try {
2060                        try {
2061                            synchronized(this) {
2062                                final long now = SystemClock.uptimeMillis();
2063                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2064                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2065                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2066                                //        + ", write delay=" + nextWriteDelay);
2067                                if (nextWriteDelay < nextCpuDelay) {
2068                                    nextCpuDelay = nextWriteDelay;
2069                                }
2070                                if (nextCpuDelay > 0) {
2071                                    mProcessCpuMutexFree.set(true);
2072                                    this.wait(nextCpuDelay);
2073                                }
2074                            }
2075                        } catch (InterruptedException e) {
2076                        }
2077                        updateCpuStatsNow();
2078                    } catch (Exception e) {
2079                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2080                    }
2081                }
2082            }
2083        };
2084
2085        Watchdog.getInstance().addMonitor(this);
2086        Watchdog.getInstance().addThread(mHandler);
2087    }
2088
2089    public void setSystemServiceManager(SystemServiceManager mgr) {
2090        mSystemServiceManager = mgr;
2091    }
2092
2093    public void setInstaller(Installer installer) {
2094        mInstaller = installer;
2095    }
2096
2097    private void start() {
2098        Process.removeAllProcessGroups();
2099        mProcessCpuThread.start();
2100
2101        mBatteryStatsService.publish(mContext);
2102        mAppOpsService.publish(mContext);
2103        Slog.d("AppOps", "AppOpsService published");
2104        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2105    }
2106
2107    public void initPowerManagement() {
2108        mStackSupervisor.initPowerManagement();
2109        mBatteryStatsService.initPowerManagement();
2110    }
2111
2112    @Override
2113    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2114            throws RemoteException {
2115        if (code == SYSPROPS_TRANSACTION) {
2116            // We need to tell all apps about the system property change.
2117            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2118            synchronized(this) {
2119                final int NP = mProcessNames.getMap().size();
2120                for (int ip=0; ip<NP; ip++) {
2121                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2122                    final int NA = apps.size();
2123                    for (int ia=0; ia<NA; ia++) {
2124                        ProcessRecord app = apps.valueAt(ia);
2125                        if (app.thread != null) {
2126                            procs.add(app.thread.asBinder());
2127                        }
2128                    }
2129                }
2130            }
2131
2132            int N = procs.size();
2133            for (int i=0; i<N; i++) {
2134                Parcel data2 = Parcel.obtain();
2135                try {
2136                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2137                } catch (RemoteException e) {
2138                }
2139                data2.recycle();
2140            }
2141        }
2142        try {
2143            return super.onTransact(code, data, reply, flags);
2144        } catch (RuntimeException e) {
2145            // The activity manager only throws security exceptions, so let's
2146            // log all others.
2147            if (!(e instanceof SecurityException)) {
2148                Slog.wtf(TAG, "Activity Manager Crash", e);
2149            }
2150            throw e;
2151        }
2152    }
2153
2154    void updateCpuStats() {
2155        final long now = SystemClock.uptimeMillis();
2156        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2157            return;
2158        }
2159        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2160            synchronized (mProcessCpuThread) {
2161                mProcessCpuThread.notify();
2162            }
2163        }
2164    }
2165
2166    void updateCpuStatsNow() {
2167        synchronized (mProcessCpuTracker) {
2168            mProcessCpuMutexFree.set(false);
2169            final long now = SystemClock.uptimeMillis();
2170            boolean haveNewCpuStats = false;
2171
2172            if (MONITOR_CPU_USAGE &&
2173                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2174                mLastCpuTime.set(now);
2175                haveNewCpuStats = true;
2176                mProcessCpuTracker.update();
2177                //Slog.i(TAG, mProcessCpu.printCurrentState());
2178                //Slog.i(TAG, "Total CPU usage: "
2179                //        + mProcessCpu.getTotalCpuPercent() + "%");
2180
2181                // Slog the cpu usage if the property is set.
2182                if ("true".equals(SystemProperties.get("events.cpu"))) {
2183                    int user = mProcessCpuTracker.getLastUserTime();
2184                    int system = mProcessCpuTracker.getLastSystemTime();
2185                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2186                    int irq = mProcessCpuTracker.getLastIrqTime();
2187                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2188                    int idle = mProcessCpuTracker.getLastIdleTime();
2189
2190                    int total = user + system + iowait + irq + softIrq + idle;
2191                    if (total == 0) total = 1;
2192
2193                    EventLog.writeEvent(EventLogTags.CPU,
2194                            ((user+system+iowait+irq+softIrq) * 100) / total,
2195                            (user * 100) / total,
2196                            (system * 100) / total,
2197                            (iowait * 100) / total,
2198                            (irq * 100) / total,
2199                            (softIrq * 100) / total);
2200                }
2201            }
2202
2203            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2204            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2205            synchronized(bstats) {
2206                synchronized(mPidsSelfLocked) {
2207                    if (haveNewCpuStats) {
2208                        if (mOnBattery) {
2209                            int perc = bstats.startAddingCpuLocked();
2210                            int totalUTime = 0;
2211                            int totalSTime = 0;
2212                            final int N = mProcessCpuTracker.countStats();
2213                            for (int i=0; i<N; i++) {
2214                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2215                                if (!st.working) {
2216                                    continue;
2217                                }
2218                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2219                                int otherUTime = (st.rel_utime*perc)/100;
2220                                int otherSTime = (st.rel_stime*perc)/100;
2221                                totalUTime += otherUTime;
2222                                totalSTime += otherSTime;
2223                                if (pr != null) {
2224                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2225                                    if (ps == null || !ps.isActive()) {
2226                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2227                                                pr.info.uid, pr.processName);
2228                                    }
2229                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2230                                            st.rel_stime-otherSTime);
2231                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2232                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2233                                } else {
2234                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2235                                    if (ps == null || !ps.isActive()) {
2236                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2237                                                bstats.mapUid(st.uid), st.name);
2238                                    }
2239                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2240                                            st.rel_stime-otherSTime);
2241                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2242                                }
2243                            }
2244                            bstats.finishAddingCpuLocked(perc, totalUTime,
2245                                    totalSTime, cpuSpeedTimes);
2246                        }
2247                    }
2248                }
2249
2250                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2251                    mLastWriteTime = now;
2252                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2253                }
2254            }
2255        }
2256    }
2257
2258    @Override
2259    public void batteryNeedsCpuUpdate() {
2260        updateCpuStatsNow();
2261    }
2262
2263    @Override
2264    public void batteryPowerChanged(boolean onBattery) {
2265        // When plugging in, update the CPU stats first before changing
2266        // the plug state.
2267        updateCpuStatsNow();
2268        synchronized (this) {
2269            synchronized(mPidsSelfLocked) {
2270                mOnBattery = DEBUG_POWER ? true : onBattery;
2271            }
2272        }
2273    }
2274
2275    /**
2276     * Initialize the application bind args. These are passed to each
2277     * process when the bindApplication() IPC is sent to the process. They're
2278     * lazily setup to make sure the services are running when they're asked for.
2279     */
2280    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2281        if (mAppBindArgs == null) {
2282            mAppBindArgs = new HashMap<>();
2283
2284            // Isolated processes won't get this optimization, so that we don't
2285            // violate the rules about which services they have access to.
2286            if (!isolated) {
2287                // Setup the application init args
2288                mAppBindArgs.put("package", ServiceManager.getService("package"));
2289                mAppBindArgs.put("window", ServiceManager.getService("window"));
2290                mAppBindArgs.put(Context.ALARM_SERVICE,
2291                        ServiceManager.getService(Context.ALARM_SERVICE));
2292            }
2293        }
2294        return mAppBindArgs;
2295    }
2296
2297    final void setFocusedActivityLocked(ActivityRecord r) {
2298        if (mFocusedActivity != r) {
2299            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2300            mFocusedActivity = r;
2301            if (r.task != null && r.task.voiceInteractor != null) {
2302                startRunningVoiceLocked();
2303            } else {
2304                finishRunningVoiceLocked();
2305            }
2306            mStackSupervisor.setFocusedStack(r);
2307            if (r != null) {
2308                mWindowManager.setFocusedApp(r.appToken, true);
2309            }
2310            applyUpdateLockStateLocked(r);
2311        }
2312    }
2313
2314    final void clearFocusedActivity(ActivityRecord r) {
2315        if (mFocusedActivity == r) {
2316            mFocusedActivity = null;
2317        }
2318    }
2319
2320    @Override
2321    public void setFocusedStack(int stackId) {
2322        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2323        synchronized (ActivityManagerService.this) {
2324            ActivityStack stack = mStackSupervisor.getStack(stackId);
2325            if (stack != null) {
2326                ActivityRecord r = stack.topRunningActivityLocked(null);
2327                if (r != null) {
2328                    setFocusedActivityLocked(r);
2329                }
2330            }
2331        }
2332    }
2333
2334    @Override
2335    public void notifyActivityDrawn(IBinder token) {
2336        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2337        synchronized (this) {
2338            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2339            if (r != null) {
2340                r.task.stack.notifyActivityDrawnLocked(r);
2341            }
2342        }
2343    }
2344
2345    final void applyUpdateLockStateLocked(ActivityRecord r) {
2346        // Modifications to the UpdateLock state are done on our handler, outside
2347        // the activity manager's locks.  The new state is determined based on the
2348        // state *now* of the relevant activity record.  The object is passed to
2349        // the handler solely for logging detail, not to be consulted/modified.
2350        final boolean nextState = r != null && r.immersive;
2351        mHandler.sendMessage(
2352                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2353    }
2354
2355    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2356        Message msg = Message.obtain();
2357        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2358        msg.obj = r.task.askedCompatMode ? null : r;
2359        mHandler.sendMessage(msg);
2360    }
2361
2362    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2363            String what, Object obj, ProcessRecord srcApp) {
2364        app.lastActivityTime = now;
2365
2366        if (app.activities.size() > 0) {
2367            // Don't want to touch dependent processes that are hosting activities.
2368            return index;
2369        }
2370
2371        int lrui = mLruProcesses.lastIndexOf(app);
2372        if (lrui < 0) {
2373            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2374                    + what + " " + obj + " from " + srcApp);
2375            return index;
2376        }
2377
2378        if (lrui >= index) {
2379            // Don't want to cause this to move dependent processes *back* in the
2380            // list as if they were less frequently used.
2381            return index;
2382        }
2383
2384        if (lrui >= mLruProcessActivityStart) {
2385            // Don't want to touch dependent processes that are hosting activities.
2386            return index;
2387        }
2388
2389        mLruProcesses.remove(lrui);
2390        if (index > 0) {
2391            index--;
2392        }
2393        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2394                + " in LRU list: " + app);
2395        mLruProcesses.add(index, app);
2396        return index;
2397    }
2398
2399    final void removeLruProcessLocked(ProcessRecord app) {
2400        int lrui = mLruProcesses.lastIndexOf(app);
2401        if (lrui >= 0) {
2402            if (!app.killed) {
2403                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2404                Process.killProcessQuiet(app.pid);
2405                Process.killProcessGroup(app.info.uid, app.pid);
2406            }
2407            if (lrui <= mLruProcessActivityStart) {
2408                mLruProcessActivityStart--;
2409            }
2410            if (lrui <= mLruProcessServiceStart) {
2411                mLruProcessServiceStart--;
2412            }
2413            mLruProcesses.remove(lrui);
2414        }
2415    }
2416
2417    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2418            ProcessRecord client) {
2419        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2420                || app.treatLikeActivity;
2421        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2422        if (!activityChange && hasActivity) {
2423            // The process has activities, so we are only allowing activity-based adjustments
2424            // to move it.  It should be kept in the front of the list with other
2425            // processes that have activities, and we don't want those to change their
2426            // order except due to activity operations.
2427            return;
2428        }
2429
2430        mLruSeq++;
2431        final long now = SystemClock.uptimeMillis();
2432        app.lastActivityTime = now;
2433
2434        // First a quick reject: if the app is already at the position we will
2435        // put it, then there is nothing to do.
2436        if (hasActivity) {
2437            final int N = mLruProcesses.size();
2438            if (N > 0 && mLruProcesses.get(N-1) == app) {
2439                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2440                return;
2441            }
2442        } else {
2443            if (mLruProcessServiceStart > 0
2444                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2445                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2446                return;
2447            }
2448        }
2449
2450        int lrui = mLruProcesses.lastIndexOf(app);
2451
2452        if (app.persistent && lrui >= 0) {
2453            // We don't care about the position of persistent processes, as long as
2454            // they are in the list.
2455            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2456            return;
2457        }
2458
2459        /* In progress: compute new position first, so we can avoid doing work
2460           if the process is not actually going to move.  Not yet working.
2461        int addIndex;
2462        int nextIndex;
2463        boolean inActivity = false, inService = false;
2464        if (hasActivity) {
2465            // Process has activities, put it at the very tipsy-top.
2466            addIndex = mLruProcesses.size();
2467            nextIndex = mLruProcessServiceStart;
2468            inActivity = true;
2469        } else if (hasService) {
2470            // Process has services, put it at the top of the service list.
2471            addIndex = mLruProcessActivityStart;
2472            nextIndex = mLruProcessServiceStart;
2473            inActivity = true;
2474            inService = true;
2475        } else  {
2476            // Process not otherwise of interest, it goes to the top of the non-service area.
2477            addIndex = mLruProcessServiceStart;
2478            if (client != null) {
2479                int clientIndex = mLruProcesses.lastIndexOf(client);
2480                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2481                        + app);
2482                if (clientIndex >= 0 && addIndex > clientIndex) {
2483                    addIndex = clientIndex;
2484                }
2485            }
2486            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2487        }
2488
2489        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2490                + mLruProcessActivityStart + "): " + app);
2491        */
2492
2493        if (lrui >= 0) {
2494            if (lrui < mLruProcessActivityStart) {
2495                mLruProcessActivityStart--;
2496            }
2497            if (lrui < mLruProcessServiceStart) {
2498                mLruProcessServiceStart--;
2499            }
2500            /*
2501            if (addIndex > lrui) {
2502                addIndex--;
2503            }
2504            if (nextIndex > lrui) {
2505                nextIndex--;
2506            }
2507            */
2508            mLruProcesses.remove(lrui);
2509        }
2510
2511        /*
2512        mLruProcesses.add(addIndex, app);
2513        if (inActivity) {
2514            mLruProcessActivityStart++;
2515        }
2516        if (inService) {
2517            mLruProcessActivityStart++;
2518        }
2519        */
2520
2521        int nextIndex;
2522        if (hasActivity) {
2523            final int N = mLruProcesses.size();
2524            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2525                // Process doesn't have activities, but has clients with
2526                // activities...  move it up, but one below the top (the top
2527                // should always have a real activity).
2528                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2529                mLruProcesses.add(N-1, app);
2530                // To keep it from spamming the LRU list (by making a bunch of clients),
2531                // we will push down any other entries owned by the app.
2532                final int uid = app.info.uid;
2533                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2534                    ProcessRecord subProc = mLruProcesses.get(i);
2535                    if (subProc.info.uid == uid) {
2536                        // We want to push this one down the list.  If the process after
2537                        // it is for the same uid, however, don't do so, because we don't
2538                        // want them internally to be re-ordered.
2539                        if (mLruProcesses.get(i-1).info.uid != uid) {
2540                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2541                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2542                            ProcessRecord tmp = mLruProcesses.get(i);
2543                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2544                            mLruProcesses.set(i-1, tmp);
2545                            i--;
2546                        }
2547                    } else {
2548                        // A gap, we can stop here.
2549                        break;
2550                    }
2551                }
2552            } else {
2553                // Process has activities, put it at the very tipsy-top.
2554                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2555                mLruProcesses.add(app);
2556            }
2557            nextIndex = mLruProcessServiceStart;
2558        } else if (hasService) {
2559            // Process has services, put it at the top of the service list.
2560            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2561            mLruProcesses.add(mLruProcessActivityStart, app);
2562            nextIndex = mLruProcessServiceStart;
2563            mLruProcessActivityStart++;
2564        } else  {
2565            // Process not otherwise of interest, it goes to the top of the non-service area.
2566            int index = mLruProcessServiceStart;
2567            if (client != null) {
2568                // If there is a client, don't allow the process to be moved up higher
2569                // in the list than that client.
2570                int clientIndex = mLruProcesses.lastIndexOf(client);
2571                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2572                        + " when updating " + app);
2573                if (clientIndex <= lrui) {
2574                    // Don't allow the client index restriction to push it down farther in the
2575                    // list than it already is.
2576                    clientIndex = lrui;
2577                }
2578                if (clientIndex >= 0 && index > clientIndex) {
2579                    index = clientIndex;
2580                }
2581            }
2582            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2583            mLruProcesses.add(index, app);
2584            nextIndex = index-1;
2585            mLruProcessActivityStart++;
2586            mLruProcessServiceStart++;
2587        }
2588
2589        // If the app is currently using a content provider or service,
2590        // bump those processes as well.
2591        for (int j=app.connections.size()-1; j>=0; j--) {
2592            ConnectionRecord cr = app.connections.valueAt(j);
2593            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2594                    && cr.binding.service.app != null
2595                    && cr.binding.service.app.lruSeq != mLruSeq
2596                    && !cr.binding.service.app.persistent) {
2597                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2598                        "service connection", cr, app);
2599            }
2600        }
2601        for (int j=app.conProviders.size()-1; j>=0; j--) {
2602            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2603            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2604                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2605                        "provider reference", cpr, app);
2606            }
2607        }
2608    }
2609
2610    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2611        if (uid == Process.SYSTEM_UID) {
2612            // The system gets to run in any process.  If there are multiple
2613            // processes with the same uid, just pick the first (this
2614            // should never happen).
2615            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2616            if (procs == null) return null;
2617            final int N = procs.size();
2618            for (int i = 0; i < N; i++) {
2619                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2620            }
2621        }
2622        ProcessRecord proc = mProcessNames.get(processName, uid);
2623        if (false && proc != null && !keepIfLarge
2624                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2625                && proc.lastCachedPss >= 4000) {
2626            // Turn this condition on to cause killing to happen regularly, for testing.
2627            if (proc.baseProcessTracker != null) {
2628                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2629            }
2630            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2631        } else if (proc != null && !keepIfLarge
2632                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2633                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2634            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2635            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2636                if (proc.baseProcessTracker != null) {
2637                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2638                }
2639                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2640            }
2641        }
2642        return proc;
2643    }
2644
2645    void ensurePackageDexOpt(String packageName) {
2646        IPackageManager pm = AppGlobals.getPackageManager();
2647        try {
2648            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2649                mDidDexOpt = true;
2650            }
2651        } catch (RemoteException e) {
2652        }
2653    }
2654
2655    boolean isNextTransitionForward() {
2656        int transit = mWindowManager.getPendingAppTransition();
2657        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2658                || transit == AppTransition.TRANSIT_TASK_OPEN
2659                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2660    }
2661
2662    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2663            String processName, String abiOverride, int uid, Runnable crashHandler) {
2664        synchronized(this) {
2665            ApplicationInfo info = new ApplicationInfo();
2666            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2667            // For isolated processes, the former contains the parent's uid and the latter the
2668            // actual uid of the isolated process.
2669            // In the special case introduced by this method (which is, starting an isolated
2670            // process directly from the SystemServer without an actual parent app process) the
2671            // closest thing to a parent's uid is SYSTEM_UID.
2672            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2673            // the |isolated| logic in the ProcessRecord constructor.
2674            info.uid = Process.SYSTEM_UID;
2675            info.processName = processName;
2676            info.className = entryPoint;
2677            info.packageName = "android";
2678            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2679                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2680                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2681                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2682                    crashHandler);
2683            return proc != null ? proc.pid : 0;
2684        }
2685    }
2686
2687    final ProcessRecord startProcessLocked(String processName,
2688            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2689            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2690            boolean isolated, boolean keepIfLarge) {
2691        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2692                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2693                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2694                null /* crashHandler */);
2695    }
2696
2697    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2698            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2699            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2700            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2701        long startTime = SystemClock.elapsedRealtime();
2702        ProcessRecord app;
2703        if (!isolated) {
2704            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2705            checkTime(startTime, "startProcess: after getProcessRecord");
2706        } else {
2707            // If this is an isolated process, it can't re-use an existing process.
2708            app = null;
2709        }
2710        // We don't have to do anything more if:
2711        // (1) There is an existing application record; and
2712        // (2) The caller doesn't think it is dead, OR there is no thread
2713        //     object attached to it so we know it couldn't have crashed; and
2714        // (3) There is a pid assigned to it, so it is either starting or
2715        //     already running.
2716        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2717                + " app=" + app + " knownToBeDead=" + knownToBeDead
2718                + " thread=" + (app != null ? app.thread : null)
2719                + " pid=" + (app != null ? app.pid : -1));
2720        if (app != null && app.pid > 0) {
2721            if (!knownToBeDead || app.thread == null) {
2722                // We already have the app running, or are waiting for it to
2723                // come up (we have a pid but not yet its thread), so keep it.
2724                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2725                // If this is a new package in the process, add the package to the list
2726                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2727                checkTime(startTime, "startProcess: done, added package to proc");
2728                return app;
2729            }
2730
2731            // An application record is attached to a previous process,
2732            // clean it up now.
2733            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2734            checkTime(startTime, "startProcess: bad proc running, killing");
2735            Process.killProcessGroup(app.info.uid, app.pid);
2736            handleAppDiedLocked(app, true, true);
2737            checkTime(startTime, "startProcess: done killing old proc");
2738        }
2739
2740        String hostingNameStr = hostingName != null
2741                ? hostingName.flattenToShortString() : null;
2742
2743        if (!isolated) {
2744            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2745                // If we are in the background, then check to see if this process
2746                // is bad.  If so, we will just silently fail.
2747                if (mBadProcesses.get(info.processName, info.uid) != null) {
2748                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2749                            + "/" + info.processName);
2750                    return null;
2751                }
2752            } else {
2753                // When the user is explicitly starting a process, then clear its
2754                // crash count so that we won't make it bad until they see at
2755                // least one crash dialog again, and make the process good again
2756                // if it had been bad.
2757                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2758                        + "/" + info.processName);
2759                mProcessCrashTimes.remove(info.processName, info.uid);
2760                if (mBadProcesses.get(info.processName, info.uid) != null) {
2761                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2762                            UserHandle.getUserId(info.uid), info.uid,
2763                            info.processName);
2764                    mBadProcesses.remove(info.processName, info.uid);
2765                    if (app != null) {
2766                        app.bad = false;
2767                    }
2768                }
2769            }
2770        }
2771
2772        if (app == null) {
2773            checkTime(startTime, "startProcess: creating new process record");
2774            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2775            app.crashHandler = crashHandler;
2776            if (app == null) {
2777                Slog.w(TAG, "Failed making new process record for "
2778                        + processName + "/" + info.uid + " isolated=" + isolated);
2779                return null;
2780            }
2781            mProcessNames.put(processName, app.uid, app);
2782            if (isolated) {
2783                mIsolatedProcesses.put(app.uid, app);
2784            }
2785            checkTime(startTime, "startProcess: done creating new process record");
2786        } else {
2787            // If this is a new package in the process, add the package to the list
2788            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2789            checkTime(startTime, "startProcess: added package to existing proc");
2790        }
2791
2792        // If the system is not ready yet, then hold off on starting this
2793        // process until it is.
2794        if (!mProcessesReady
2795                && !isAllowedWhileBooting(info)
2796                && !allowWhileBooting) {
2797            if (!mProcessesOnHold.contains(app)) {
2798                mProcessesOnHold.add(app);
2799            }
2800            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2801            checkTime(startTime, "startProcess: returning with proc on hold");
2802            return app;
2803        }
2804
2805        checkTime(startTime, "startProcess: stepping in to startProcess");
2806        startProcessLocked(
2807                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2808        checkTime(startTime, "startProcess: done starting proc!");
2809        return (app.pid != 0) ? app : null;
2810    }
2811
2812    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2813        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2814    }
2815
2816    private final void startProcessLocked(ProcessRecord app,
2817            String hostingType, String hostingNameStr) {
2818        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2819                null /* entryPoint */, null /* entryPointArgs */);
2820    }
2821
2822    private final void startProcessLocked(ProcessRecord app, String hostingType,
2823            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2824        long startTime = SystemClock.elapsedRealtime();
2825        if (app.pid > 0 && app.pid != MY_PID) {
2826            checkTime(startTime, "startProcess: removing from pids map");
2827            synchronized (mPidsSelfLocked) {
2828                mPidsSelfLocked.remove(app.pid);
2829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2830            }
2831            checkTime(startTime, "startProcess: done removing from pids map");
2832            app.setPid(0);
2833        }
2834
2835        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2836                "startProcessLocked removing on hold: " + app);
2837        mProcessesOnHold.remove(app);
2838
2839        checkTime(startTime, "startProcess: starting to update cpu stats");
2840        updateCpuStats();
2841        checkTime(startTime, "startProcess: done updating cpu stats");
2842
2843        try {
2844            int uid = app.uid;
2845
2846            int[] gids = null;
2847            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2848            if (!app.isolated) {
2849                int[] permGids = null;
2850                try {
2851                    checkTime(startTime, "startProcess: getting gids from package manager");
2852                    final PackageManager pm = mContext.getPackageManager();
2853                    permGids = pm.getPackageGids(app.info.packageName);
2854
2855                    if (Environment.isExternalStorageEmulated()) {
2856                        checkTime(startTime, "startProcess: checking external storage perm");
2857                        if (pm.checkPermission(
2858                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2859                                app.info.packageName) == PERMISSION_GRANTED) {
2860                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2861                        } else {
2862                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2863                        }
2864                    }
2865                } catch (PackageManager.NameNotFoundException e) {
2866                    Slog.w(TAG, "Unable to retrieve gids", e);
2867                }
2868
2869                /*
2870                 * Add shared application and profile GIDs so applications can share some
2871                 * resources like shared libraries and access user-wide resources
2872                 */
2873                if (permGids == null) {
2874                    gids = new int[2];
2875                } else {
2876                    gids = new int[permGids.length + 2];
2877                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2878                }
2879                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2880                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2881            }
2882            checkTime(startTime, "startProcess: building args");
2883            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2884                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2885                        && mTopComponent != null
2886                        && app.processName.equals(mTopComponent.getPackageName())) {
2887                    uid = 0;
2888                }
2889                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2890                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2891                    uid = 0;
2892                }
2893            }
2894            int debugFlags = 0;
2895            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2896                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2897                // Also turn on CheckJNI for debuggable apps. It's quite
2898                // awkward to turn on otherwise.
2899                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2900            }
2901            // Run the app in safe mode if its manifest requests so or the
2902            // system is booted in safe mode.
2903            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2904                mSafeMode == true) {
2905                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2906            }
2907            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2908                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2909            }
2910            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2911                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2912            }
2913            if ("1".equals(SystemProperties.get("debug.assert"))) {
2914                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2915            }
2916
2917            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2918            if (requiredAbi == null) {
2919                requiredAbi = Build.SUPPORTED_ABIS[0];
2920            }
2921
2922            String instructionSet = null;
2923            if (app.info.primaryCpuAbi != null) {
2924                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2925            }
2926
2927            // Start the process.  It will either succeed and return a result containing
2928            // the PID of the new process, or else throw a RuntimeException.
2929            boolean isActivityProcess = (entryPoint == null);
2930            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2931            checkTime(startTime, "startProcess: asking zygote to start proc");
2932            Process.ProcessStartResult startResult = Process.start(entryPoint,
2933                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2934                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2935                    app.info.dataDir, entryPointArgs);
2936            checkTime(startTime, "startProcess: returned from zygote!");
2937
2938            if (app.isolated) {
2939                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2940            }
2941            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2942            checkTime(startTime, "startProcess: done updating battery stats");
2943
2944            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2945                    UserHandle.getUserId(uid), startResult.pid, uid,
2946                    app.processName, hostingType,
2947                    hostingNameStr != null ? hostingNameStr : "");
2948
2949            if (app.persistent) {
2950                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2951            }
2952
2953            checkTime(startTime, "startProcess: building log message");
2954            StringBuilder buf = mStringBuilder;
2955            buf.setLength(0);
2956            buf.append("Start proc ");
2957            buf.append(app.processName);
2958            if (!isActivityProcess) {
2959                buf.append(" [");
2960                buf.append(entryPoint);
2961                buf.append("]");
2962            }
2963            buf.append(" for ");
2964            buf.append(hostingType);
2965            if (hostingNameStr != null) {
2966                buf.append(" ");
2967                buf.append(hostingNameStr);
2968            }
2969            buf.append(": pid=");
2970            buf.append(startResult.pid);
2971            buf.append(" uid=");
2972            buf.append(uid);
2973            buf.append(" gids={");
2974            if (gids != null) {
2975                for (int gi=0; gi<gids.length; gi++) {
2976                    if (gi != 0) buf.append(", ");
2977                    buf.append(gids[gi]);
2978
2979                }
2980            }
2981            buf.append("}");
2982            if (requiredAbi != null) {
2983                buf.append(" abi=");
2984                buf.append(requiredAbi);
2985            }
2986            Slog.i(TAG, buf.toString());
2987            app.setPid(startResult.pid);
2988            app.usingWrapper = startResult.usingWrapper;
2989            app.removed = false;
2990            app.killed = false;
2991            app.killedByAm = false;
2992            checkTime(startTime, "startProcess: starting to update pids map");
2993            synchronized (mPidsSelfLocked) {
2994                this.mPidsSelfLocked.put(startResult.pid, app);
2995                if (isActivityProcess) {
2996                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2997                    msg.obj = app;
2998                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2999                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3000                }
3001            }
3002            checkTime(startTime, "startProcess: done updating pids map");
3003        } catch (RuntimeException e) {
3004            // XXX do better error recovery.
3005            app.setPid(0);
3006            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3007            if (app.isolated) {
3008                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3009            }
3010            Slog.e(TAG, "Failure starting process " + app.processName, e);
3011        }
3012    }
3013
3014    void updateUsageStats(ActivityRecord component, boolean resumed) {
3015        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3016        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3017        if (resumed) {
3018            if (mUsageStatsService != null) {
3019                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3020                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3021            }
3022            synchronized (stats) {
3023                stats.noteActivityResumedLocked(component.app.uid);
3024            }
3025        } else {
3026            if (mUsageStatsService != null) {
3027                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3028                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3029            }
3030            synchronized (stats) {
3031                stats.noteActivityPausedLocked(component.app.uid);
3032            }
3033        }
3034    }
3035
3036    Intent getHomeIntent() {
3037        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3038        intent.setComponent(mTopComponent);
3039        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3040            intent.addCategory(Intent.CATEGORY_HOME);
3041        }
3042        return intent;
3043    }
3044
3045    boolean startHomeActivityLocked(int userId) {
3046        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3047                && mTopAction == null) {
3048            // We are running in factory test mode, but unable to find
3049            // the factory test app, so just sit around displaying the
3050            // error message and don't try to start anything.
3051            return false;
3052        }
3053        Intent intent = getHomeIntent();
3054        ActivityInfo aInfo =
3055            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3056        if (aInfo != null) {
3057            intent.setComponent(new ComponentName(
3058                    aInfo.applicationInfo.packageName, aInfo.name));
3059            // Don't do this if the home app is currently being
3060            // instrumented.
3061            aInfo = new ActivityInfo(aInfo);
3062            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3063            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3064                    aInfo.applicationInfo.uid, true);
3065            if (app == null || app.instrumentationClass == null) {
3066                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3067                mStackSupervisor.startHomeActivity(intent, aInfo);
3068            }
3069        }
3070
3071        return true;
3072    }
3073
3074    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3075        ActivityInfo ai = null;
3076        ComponentName comp = intent.getComponent();
3077        try {
3078            if (comp != null) {
3079                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3080            } else {
3081                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3082                        intent,
3083                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3084                            flags, userId);
3085
3086                if (info != null) {
3087                    ai = info.activityInfo;
3088                }
3089            }
3090        } catch (RemoteException e) {
3091            // ignore
3092        }
3093
3094        return ai;
3095    }
3096
3097    /**
3098     * Starts the "new version setup screen" if appropriate.
3099     */
3100    void startSetupActivityLocked() {
3101        // Only do this once per boot.
3102        if (mCheckedForSetup) {
3103            return;
3104        }
3105
3106        // We will show this screen if the current one is a different
3107        // version than the last one shown, and we are not running in
3108        // low-level factory test mode.
3109        final ContentResolver resolver = mContext.getContentResolver();
3110        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3111                Settings.Global.getInt(resolver,
3112                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3113            mCheckedForSetup = true;
3114
3115            // See if we should be showing the platform update setup UI.
3116            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3117            List<ResolveInfo> ris = mContext.getPackageManager()
3118                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3119
3120            // We don't allow third party apps to replace this.
3121            ResolveInfo ri = null;
3122            for (int i=0; ris != null && i<ris.size(); i++) {
3123                if ((ris.get(i).activityInfo.applicationInfo.flags
3124                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3125                    ri = ris.get(i);
3126                    break;
3127                }
3128            }
3129
3130            if (ri != null) {
3131                String vers = ri.activityInfo.metaData != null
3132                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3133                        : null;
3134                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3135                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3136                            Intent.METADATA_SETUP_VERSION);
3137                }
3138                String lastVers = Settings.Secure.getString(
3139                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3140                if (vers != null && !vers.equals(lastVers)) {
3141                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3142                    intent.setComponent(new ComponentName(
3143                            ri.activityInfo.packageName, ri.activityInfo.name));
3144                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3145                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3146                            null);
3147                }
3148            }
3149        }
3150    }
3151
3152    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3153        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3154    }
3155
3156    void enforceNotIsolatedCaller(String caller) {
3157        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3158            throw new SecurityException("Isolated process not allowed to call " + caller);
3159        }
3160    }
3161
3162    void enforceShellRestriction(String restriction, int userHandle) {
3163        if (Binder.getCallingUid() == Process.SHELL_UID) {
3164            if (userHandle < 0
3165                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3166                throw new SecurityException("Shell does not have permission to access user "
3167                        + userHandle);
3168            }
3169        }
3170    }
3171
3172    @Override
3173    public int getFrontActivityScreenCompatMode() {
3174        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3175        synchronized (this) {
3176            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3177        }
3178    }
3179
3180    @Override
3181    public void setFrontActivityScreenCompatMode(int mode) {
3182        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3183                "setFrontActivityScreenCompatMode");
3184        synchronized (this) {
3185            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3186        }
3187    }
3188
3189    @Override
3190    public int getPackageScreenCompatMode(String packageName) {
3191        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3192        synchronized (this) {
3193            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3194        }
3195    }
3196
3197    @Override
3198    public void setPackageScreenCompatMode(String packageName, int mode) {
3199        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3200                "setPackageScreenCompatMode");
3201        synchronized (this) {
3202            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3203        }
3204    }
3205
3206    @Override
3207    public boolean getPackageAskScreenCompat(String packageName) {
3208        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3209        synchronized (this) {
3210            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3211        }
3212    }
3213
3214    @Override
3215    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3216        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3217                "setPackageAskScreenCompat");
3218        synchronized (this) {
3219            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3220        }
3221    }
3222
3223    private void dispatchProcessesChanged() {
3224        int N;
3225        synchronized (this) {
3226            N = mPendingProcessChanges.size();
3227            if (mActiveProcessChanges.length < N) {
3228                mActiveProcessChanges = new ProcessChangeItem[N];
3229            }
3230            mPendingProcessChanges.toArray(mActiveProcessChanges);
3231            mAvailProcessChanges.addAll(mPendingProcessChanges);
3232            mPendingProcessChanges.clear();
3233            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3234        }
3235
3236        int i = mProcessObservers.beginBroadcast();
3237        while (i > 0) {
3238            i--;
3239            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3240            if (observer != null) {
3241                try {
3242                    for (int j=0; j<N; j++) {
3243                        ProcessChangeItem item = mActiveProcessChanges[j];
3244                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3245                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3246                                    + item.pid + " uid=" + item.uid + ": "
3247                                    + item.foregroundActivities);
3248                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3249                                    item.foregroundActivities);
3250                        }
3251                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3252                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3253                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3254                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3255                        }
3256                    }
3257                } catch (RemoteException e) {
3258                }
3259            }
3260        }
3261        mProcessObservers.finishBroadcast();
3262    }
3263
3264    private void dispatchProcessDied(int pid, int uid) {
3265        int i = mProcessObservers.beginBroadcast();
3266        while (i > 0) {
3267            i--;
3268            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3269            if (observer != null) {
3270                try {
3271                    observer.onProcessDied(pid, uid);
3272                } catch (RemoteException e) {
3273                }
3274            }
3275        }
3276        mProcessObservers.finishBroadcast();
3277    }
3278
3279    @Override
3280    public final int startActivity(IApplicationThread caller, String callingPackage,
3281            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3282            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3283        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3284            resultWho, requestCode, startFlags, profilerInfo, options,
3285            UserHandle.getCallingUserId());
3286    }
3287
3288    @Override
3289    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3290            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3291            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3292        enforceNotIsolatedCaller("startActivity");
3293        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3294                false, ALLOW_FULL_ONLY, "startActivity", null);
3295        // TODO: Switch to user app stacks here.
3296        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3297                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3298                profilerInfo, null, null, options, userId, null, null);
3299    }
3300
3301    @Override
3302    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3303            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3304            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3305
3306        // This is very dangerous -- it allows you to perform a start activity (including
3307        // permission grants) as any app that may launch one of your own activities.  So
3308        // we will only allow this to be done from activities that are part of the core framework,
3309        // and then only when they are running as the system.
3310        final ActivityRecord sourceRecord;
3311        final int targetUid;
3312        final String targetPackage;
3313        synchronized (this) {
3314            if (resultTo == null) {
3315                throw new SecurityException("Must be called from an activity");
3316            }
3317            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3318            if (sourceRecord == null) {
3319                throw new SecurityException("Called with bad activity token: " + resultTo);
3320            }
3321            if (!sourceRecord.info.packageName.equals("android")) {
3322                throw new SecurityException(
3323                        "Must be called from an activity that is declared in the android package");
3324            }
3325            if (sourceRecord.app == null) {
3326                throw new SecurityException("Called without a process attached to activity");
3327            }
3328            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3329                // This is still okay, as long as this activity is running under the
3330                // uid of the original calling activity.
3331                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3332                    throw new SecurityException(
3333                            "Calling activity in uid " + sourceRecord.app.uid
3334                                    + " must be system uid or original calling uid "
3335                                    + sourceRecord.launchedFromUid);
3336                }
3337            }
3338            targetUid = sourceRecord.launchedFromUid;
3339            targetPackage = sourceRecord.launchedFromPackage;
3340        }
3341
3342        if (userId == UserHandle.USER_NULL) {
3343            userId = UserHandle.getUserId(sourceRecord.app.uid);
3344        }
3345
3346        // TODO: Switch to user app stacks here.
3347        try {
3348            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3349                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3350                    null, null, options, userId, null, null);
3351            return ret;
3352        } catch (SecurityException e) {
3353            // XXX need to figure out how to propagate to original app.
3354            // A SecurityException here is generally actually a fault of the original
3355            // calling activity (such as a fairly granting permissions), so propagate it
3356            // back to them.
3357            /*
3358            StringBuilder msg = new StringBuilder();
3359            msg.append("While launching");
3360            msg.append(intent.toString());
3361            msg.append(": ");
3362            msg.append(e.getMessage());
3363            */
3364            throw e;
3365        }
3366    }
3367
3368    @Override
3369    public final WaitResult startActivityAndWait(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("startActivityAndWait");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3375        WaitResult res = new WaitResult();
3376        // TODO: Switch to user app stacks here.
3377        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3378                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3379                options, userId, null, null);
3380        return res;
3381    }
3382
3383    @Override
3384    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3385            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3386            int startFlags, Configuration config, Bundle options, int userId) {
3387        enforceNotIsolatedCaller("startActivityWithConfig");
3388        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3389                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3390        // TODO: Switch to user app stacks here.
3391        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3392                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3393                null, null, config, options, userId, null, null);
3394        return ret;
3395    }
3396
3397    @Override
3398    public int startActivityIntentSender(IApplicationThread caller,
3399            IntentSender intent, Intent fillInIntent, String resolvedType,
3400            IBinder resultTo, String resultWho, int requestCode,
3401            int flagsMask, int flagsValues, Bundle options) {
3402        enforceNotIsolatedCaller("startActivityIntentSender");
3403        // Refuse possible leaked file descriptors
3404        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3405            throw new IllegalArgumentException("File descriptors passed in Intent");
3406        }
3407
3408        IIntentSender sender = intent.getTarget();
3409        if (!(sender instanceof PendingIntentRecord)) {
3410            throw new IllegalArgumentException("Bad PendingIntent object");
3411        }
3412
3413        PendingIntentRecord pir = (PendingIntentRecord)sender;
3414
3415        synchronized (this) {
3416            // If this is coming from the currently resumed activity, it is
3417            // effectively saying that app switches are allowed at this point.
3418            final ActivityStack stack = getFocusedStack();
3419            if (stack.mResumedActivity != null &&
3420                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3421                mAppSwitchesAllowedTime = 0;
3422            }
3423        }
3424        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3425                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3426        return ret;
3427    }
3428
3429    @Override
3430    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3431            Intent intent, String resolvedType, IVoiceInteractionSession session,
3432            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3433            Bundle options, int userId) {
3434        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3435                != PackageManager.PERMISSION_GRANTED) {
3436            String msg = "Permission Denial: startVoiceActivity() from pid="
3437                    + Binder.getCallingPid()
3438                    + ", uid=" + Binder.getCallingUid()
3439                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3440            Slog.w(TAG, msg);
3441            throw new SecurityException(msg);
3442        }
3443        if (session == null || interactor == null) {
3444            throw new NullPointerException("null session or interactor");
3445        }
3446        userId = handleIncomingUser(callingPid, callingUid, userId,
3447                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3448        // TODO: Switch to user app stacks here.
3449        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3450                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3451                null, options, userId, null, null);
3452    }
3453
3454    @Override
3455    public boolean startNextMatchingActivity(IBinder callingActivity,
3456            Intent intent, Bundle options) {
3457        // Refuse possible leaked file descriptors
3458        if (intent != null && intent.hasFileDescriptors() == true) {
3459            throw new IllegalArgumentException("File descriptors passed in Intent");
3460        }
3461
3462        synchronized (this) {
3463            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3464            if (r == null) {
3465                ActivityOptions.abort(options);
3466                return false;
3467            }
3468            if (r.app == null || r.app.thread == null) {
3469                // The caller is not running...  d'oh!
3470                ActivityOptions.abort(options);
3471                return false;
3472            }
3473            intent = new Intent(intent);
3474            // The caller is not allowed to change the data.
3475            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3476            // And we are resetting to find the next component...
3477            intent.setComponent(null);
3478
3479            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3480
3481            ActivityInfo aInfo = null;
3482            try {
3483                List<ResolveInfo> resolves =
3484                    AppGlobals.getPackageManager().queryIntentActivities(
3485                            intent, r.resolvedType,
3486                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3487                            UserHandle.getCallingUserId());
3488
3489                // Look for the original activity in the list...
3490                final int N = resolves != null ? resolves.size() : 0;
3491                for (int i=0; i<N; i++) {
3492                    ResolveInfo rInfo = resolves.get(i);
3493                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3494                            && rInfo.activityInfo.name.equals(r.info.name)) {
3495                        // We found the current one...  the next matching is
3496                        // after it.
3497                        i++;
3498                        if (i<N) {
3499                            aInfo = resolves.get(i).activityInfo;
3500                        }
3501                        if (debug) {
3502                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3503                                    + "/" + r.info.name);
3504                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3505                                    + "/" + aInfo.name);
3506                        }
3507                        break;
3508                    }
3509                }
3510            } catch (RemoteException e) {
3511            }
3512
3513            if (aInfo == null) {
3514                // Nobody who is next!
3515                ActivityOptions.abort(options);
3516                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3517                return false;
3518            }
3519
3520            intent.setComponent(new ComponentName(
3521                    aInfo.applicationInfo.packageName, aInfo.name));
3522            intent.setFlags(intent.getFlags()&~(
3523                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3524                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3525                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3526                    Intent.FLAG_ACTIVITY_NEW_TASK));
3527
3528            // Okay now we need to start the new activity, replacing the
3529            // currently running activity.  This is a little tricky because
3530            // we want to start the new one as if the current one is finished,
3531            // but not finish the current one first so that there is no flicker.
3532            // And thus...
3533            final boolean wasFinishing = r.finishing;
3534            r.finishing = true;
3535
3536            // Propagate reply information over to the new activity.
3537            final ActivityRecord resultTo = r.resultTo;
3538            final String resultWho = r.resultWho;
3539            final int requestCode = r.requestCode;
3540            r.resultTo = null;
3541            if (resultTo != null) {
3542                resultTo.removeResultsLocked(r, resultWho, requestCode);
3543            }
3544
3545            final long origId = Binder.clearCallingIdentity();
3546            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3547                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3548                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3549                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3550            Binder.restoreCallingIdentity(origId);
3551
3552            r.finishing = wasFinishing;
3553            if (res != ActivityManager.START_SUCCESS) {
3554                return false;
3555            }
3556            return true;
3557        }
3558    }
3559
3560    @Override
3561    public final int startActivityFromRecents(int taskId, Bundle options) {
3562        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3563            String msg = "Permission Denial: startActivityFromRecents called without " +
3564                    START_TASKS_FROM_RECENTS;
3565            Slog.w(TAG, msg);
3566            throw new SecurityException(msg);
3567        }
3568        return startActivityFromRecentsInner(taskId, options);
3569    }
3570
3571    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3572        final TaskRecord task;
3573        final int callingUid;
3574        final String callingPackage;
3575        final Intent intent;
3576        final int userId;
3577        synchronized (this) {
3578            task = recentTaskForIdLocked(taskId);
3579            if (task == null) {
3580                throw new IllegalArgumentException("Task " + taskId + " not found.");
3581            }
3582            callingUid = task.mCallingUid;
3583            callingPackage = task.mCallingPackage;
3584            intent = task.intent;
3585            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3586            userId = task.userId;
3587        }
3588        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3589                options, userId, null, task);
3590    }
3591
3592    final int startActivityInPackage(int uid, String callingPackage,
3593            Intent intent, String resolvedType, IBinder resultTo,
3594            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3595            IActivityContainer container, TaskRecord inTask) {
3596
3597        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3598                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3599
3600        // TODO: Switch to user app stacks here.
3601        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3602                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3603                null, null, null, options, userId, container, inTask);
3604        return ret;
3605    }
3606
3607    @Override
3608    public final int startActivities(IApplicationThread caller, String callingPackage,
3609            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3610            int userId) {
3611        enforceNotIsolatedCaller("startActivities");
3612        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3613                false, ALLOW_FULL_ONLY, "startActivity", null);
3614        // TODO: Switch to user app stacks here.
3615        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3616                resolvedTypes, resultTo, options, userId);
3617        return ret;
3618    }
3619
3620    final int startActivitiesInPackage(int uid, String callingPackage,
3621            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3622            Bundle options, int userId) {
3623
3624        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3625                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3626        // TODO: Switch to user app stacks here.
3627        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3628                resultTo, options, userId);
3629        return ret;
3630    }
3631
3632    //explicitly remove thd old information in mRecentTasks when removing existing user.
3633    private void removeRecentTasksForUserLocked(int userId) {
3634        if(userId <= 0) {
3635            Slog.i(TAG, "Can't remove recent task on user " + userId);
3636            return;
3637        }
3638
3639        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3640            TaskRecord tr = mRecentTasks.get(i);
3641            if (tr.userId == userId) {
3642                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3643                        + " when finishing user" + userId);
3644                mRecentTasks.remove(i);
3645                tr.removedFromRecents(mTaskPersister);
3646            }
3647        }
3648
3649        // Remove tasks from persistent storage.
3650        mTaskPersister.wakeup(null, true);
3651    }
3652
3653    // Sort by taskId
3654    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3655        @Override
3656        public int compare(TaskRecord lhs, TaskRecord rhs) {
3657            return rhs.taskId - lhs.taskId;
3658        }
3659    };
3660
3661    // Extract the affiliates of the chain containing mRecentTasks[start].
3662    private int processNextAffiliateChain(int start) {
3663        final TaskRecord startTask = mRecentTasks.get(start);
3664        final int affiliateId = startTask.mAffiliatedTaskId;
3665
3666        // Quick identification of isolated tasks. I.e. those not launched behind.
3667        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3668                startTask.mNextAffiliate == null) {
3669            // There is still a slim chance that there are other tasks that point to this task
3670            // and that the chain is so messed up that this task no longer points to them but
3671            // the gain of this optimization outweighs the risk.
3672            startTask.inRecents = true;
3673            return start + 1;
3674        }
3675
3676        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3677        mTmpRecents.clear();
3678        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3679            final TaskRecord task = mRecentTasks.get(i);
3680            if (task.mAffiliatedTaskId == affiliateId) {
3681                mRecentTasks.remove(i);
3682                mTmpRecents.add(task);
3683            }
3684        }
3685
3686        // Sort them all by taskId. That is the order they were create in and that order will
3687        // always be correct.
3688        Collections.sort(mTmpRecents, mTaskRecordComparator);
3689
3690        // Go through and fix up the linked list.
3691        // The first one is the end of the chain and has no next.
3692        final TaskRecord first = mTmpRecents.get(0);
3693        first.inRecents = true;
3694        if (first.mNextAffiliate != null) {
3695            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3696            first.setNextAffiliate(null);
3697            mTaskPersister.wakeup(first, false);
3698        }
3699        // Everything in the middle is doubly linked from next to prev.
3700        final int tmpSize = mTmpRecents.size();
3701        for (int i = 0; i < tmpSize - 1; ++i) {
3702            final TaskRecord next = mTmpRecents.get(i);
3703            final TaskRecord prev = mTmpRecents.get(i + 1);
3704            if (next.mPrevAffiliate != prev) {
3705                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3706                        " setting prev=" + prev);
3707                next.setPrevAffiliate(prev);
3708                mTaskPersister.wakeup(next, false);
3709            }
3710            if (prev.mNextAffiliate != next) {
3711                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3712                        " setting next=" + next);
3713                prev.setNextAffiliate(next);
3714                mTaskPersister.wakeup(prev, false);
3715            }
3716            prev.inRecents = true;
3717        }
3718        // The last one is the beginning of the list and has no prev.
3719        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3720        if (last.mPrevAffiliate != null) {
3721            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3722            last.setPrevAffiliate(null);
3723            mTaskPersister.wakeup(last, false);
3724        }
3725
3726        // Insert the group back into mRecentTasks at start.
3727        mRecentTasks.addAll(start, mTmpRecents);
3728
3729        // Let the caller know where we left off.
3730        return start + tmpSize;
3731    }
3732
3733    /**
3734     * Update the recent tasks lists: make sure tasks should still be here (their
3735     * applications / activities still exist), update their availability, fixup ordering
3736     * of affiliations.
3737     */
3738    void cleanupRecentTasksLocked(int userId) {
3739        if (mRecentTasks == null) {
3740            // Happens when called from the packagemanager broadcast before boot.
3741            return;
3742        }
3743
3744        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3745        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3746        final IPackageManager pm = AppGlobals.getPackageManager();
3747        final ActivityInfo dummyAct = new ActivityInfo();
3748        final ApplicationInfo dummyApp = new ApplicationInfo();
3749
3750        int N = mRecentTasks.size();
3751
3752        int[] users = userId == UserHandle.USER_ALL
3753                ? getUsersLocked() : new int[] { userId };
3754        for (int user : users) {
3755            for (int i = 0; i < N; i++) {
3756                TaskRecord task = mRecentTasks.get(i);
3757                if (task.userId != user) {
3758                    // Only look at tasks for the user ID of interest.
3759                    continue;
3760                }
3761                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3762                    // This situation is broken, and we should just get rid of it now.
3763                    mRecentTasks.remove(i);
3764                    task.removedFromRecents(mTaskPersister);
3765                    i--;
3766                    N--;
3767                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3768                    continue;
3769                }
3770                // Check whether this activity is currently available.
3771                if (task.realActivity != null) {
3772                    ActivityInfo ai = availActCache.get(task.realActivity);
3773                    if (ai == null) {
3774                        try {
3775                            ai = pm.getActivityInfo(task.realActivity,
3776                                    PackageManager.GET_UNINSTALLED_PACKAGES
3777                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3778                        } catch (RemoteException e) {
3779                            // Will never happen.
3780                            continue;
3781                        }
3782                        if (ai == null) {
3783                            ai = dummyAct;
3784                        }
3785                        availActCache.put(task.realActivity, ai);
3786                    }
3787                    if (ai == dummyAct) {
3788                        // This could be either because the activity no longer exists, or the
3789                        // app is temporarily gone.  For the former we want to remove the recents
3790                        // entry; for the latter we want to mark it as unavailable.
3791                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3792                        if (app == null) {
3793                            try {
3794                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3795                                        PackageManager.GET_UNINSTALLED_PACKAGES
3796                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3797                            } catch (RemoteException e) {
3798                                // Will never happen.
3799                                continue;
3800                            }
3801                            if (app == null) {
3802                                app = dummyApp;
3803                            }
3804                            availAppCache.put(task.realActivity.getPackageName(), app);
3805                        }
3806                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3807                            // Doesn't exist any more!  Good-bye.
3808                            mRecentTasks.remove(i);
3809                            task.removedFromRecents(mTaskPersister);
3810                            i--;
3811                            N--;
3812                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3813                            continue;
3814                        } else {
3815                            // Otherwise just not available for now.
3816                            if (task.isAvailable) {
3817                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3818                                        + task);
3819                            }
3820                            task.isAvailable = false;
3821                        }
3822                    } else {
3823                        if (!ai.enabled || !ai.applicationInfo.enabled
3824                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3825                            if (task.isAvailable) {
3826                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3827                                        + task + " (enabled=" + ai.enabled + "/"
3828                                        + ai.applicationInfo.enabled +  " flags="
3829                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3830                            }
3831                            task.isAvailable = false;
3832                        } else {
3833                            if (!task.isAvailable) {
3834                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3835                                        + task);
3836                            }
3837                            task.isAvailable = true;
3838                        }
3839                    }
3840                }
3841            }
3842        }
3843
3844        // Verify the affiliate chain for each task.
3845        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3846        }
3847
3848        mTmpRecents.clear();
3849        // mRecentTasks is now in sorted, affiliated order.
3850    }
3851
3852    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3853        int N = mRecentTasks.size();
3854        TaskRecord top = task;
3855        int topIndex = taskIndex;
3856        while (top.mNextAffiliate != null && topIndex > 0) {
3857            top = top.mNextAffiliate;
3858            topIndex--;
3859        }
3860        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3861                + topIndex + " from intial " + taskIndex);
3862        // Find the end of the chain, doing a sanity check along the way.
3863        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3864        int endIndex = topIndex;
3865        TaskRecord prev = top;
3866        while (endIndex < N) {
3867            TaskRecord cur = mRecentTasks.get(endIndex);
3868            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3869                    + endIndex + " " + cur);
3870            if (cur == top) {
3871                // Verify start of the chain.
3872                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3873                    Slog.wtf(TAG, "Bad chain @" + endIndex
3874                            + ": first task has next affiliate: " + prev);
3875                    sane = false;
3876                    break;
3877                }
3878            } else {
3879                // Verify middle of the chain's next points back to the one before.
3880                if (cur.mNextAffiliate != prev
3881                        || cur.mNextAffiliateTaskId != prev.taskId) {
3882                    Slog.wtf(TAG, "Bad chain @" + endIndex
3883                            + ": middle task " + cur + " @" + endIndex
3884                            + " has bad next affiliate "
3885                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3886                            + ", expected " + prev);
3887                    sane = false;
3888                    break;
3889                }
3890            }
3891            if (cur.mPrevAffiliateTaskId == -1) {
3892                // Chain ends here.
3893                if (cur.mPrevAffiliate != null) {
3894                    Slog.wtf(TAG, "Bad chain @" + endIndex
3895                            + ": last task " + cur + " has previous affiliate "
3896                            + cur.mPrevAffiliate);
3897                    sane = false;
3898                }
3899                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3900                break;
3901            } else {
3902                // Verify middle of the chain's prev points to a valid item.
3903                if (cur.mPrevAffiliate == null) {
3904                    Slog.wtf(TAG, "Bad chain @" + endIndex
3905                            + ": task " + cur + " has previous affiliate "
3906                            + cur.mPrevAffiliate + " but should be id "
3907                            + cur.mPrevAffiliate);
3908                    sane = false;
3909                    break;
3910                }
3911            }
3912            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3913                Slog.wtf(TAG, "Bad chain @" + endIndex
3914                        + ": task " + cur + " has affiliated id "
3915                        + cur.mAffiliatedTaskId + " but should be "
3916                        + task.mAffiliatedTaskId);
3917                sane = false;
3918                break;
3919            }
3920            prev = cur;
3921            endIndex++;
3922            if (endIndex >= N) {
3923                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3924                        + ": last task " + prev);
3925                sane = false;
3926                break;
3927            }
3928        }
3929        if (sane) {
3930            if (endIndex < taskIndex) {
3931                Slog.wtf(TAG, "Bad chain @" + endIndex
3932                        + ": did not extend to task " + task + " @" + taskIndex);
3933                sane = false;
3934            }
3935        }
3936        if (sane) {
3937            // All looks good, we can just move all of the affiliated tasks
3938            // to the top.
3939            for (int i=topIndex; i<=endIndex; i++) {
3940                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3941                        + " from " + i + " to " + (i-topIndex));
3942                TaskRecord cur = mRecentTasks.remove(i);
3943                mRecentTasks.add(i-topIndex, cur);
3944            }
3945            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3946                    + " to " + endIndex);
3947            return true;
3948        }
3949
3950        // Whoops, couldn't do it.
3951        return false;
3952    }
3953
3954    final void addRecentTaskLocked(TaskRecord task) {
3955        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3956                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3957
3958        int N = mRecentTasks.size();
3959        // Quick case: check if the top-most recent task is the same.
3960        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3961            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3962            return;
3963        }
3964        // Another quick case: check if this is part of a set of affiliated
3965        // tasks that are at the top.
3966        if (isAffiliated && N > 0 && task.inRecents
3967                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
3968            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
3969                    + " at top when adding " + task);
3970            return;
3971        }
3972        // Another quick case: never add voice sessions.
3973        if (task.voiceSession != null) {
3974            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
3975            return;
3976        }
3977
3978        boolean needAffiliationFix = false;
3979
3980        // Slightly less quick case: the task is already in recents, so all we need
3981        // to do is move it.
3982        if (task.inRecents) {
3983            int taskIndex = mRecentTasks.indexOf(task);
3984            if (taskIndex >= 0) {
3985                if (!isAffiliated) {
3986                    // Simple case: this is not an affiliated task, so we just move it to the front.
3987                    mRecentTasks.remove(taskIndex);
3988                    mRecentTasks.add(0, task);
3989                    notifyTaskPersisterLocked(task, false);
3990                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
3991                            + " from " + taskIndex);
3992                    return;
3993                } else {
3994                    // More complicated: need to keep all affiliated tasks together.
3995                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
3996                        // All went well.
3997                        return;
3998                    }
3999
4000                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4001                    // everything and then go through our general path of adding a new task.
4002                    needAffiliationFix = true;
4003                }
4004            } else {
4005                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4006                needAffiliationFix = true;
4007            }
4008        }
4009
4010        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4011        trimRecentsForTask(task, true);
4012
4013        N = mRecentTasks.size();
4014        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4015            final TaskRecord tr = mRecentTasks.remove(N - 1);
4016            tr.removedFromRecents(mTaskPersister);
4017            N--;
4018        }
4019        task.inRecents = true;
4020        if (!isAffiliated || needAffiliationFix) {
4021            // If this is a simple non-affiliated task, or we had some failure trying to
4022            // handle it as part of an affilated task, then just place it at the top.
4023            mRecentTasks.add(0, task);
4024        } else if (isAffiliated) {
4025            // If this is a new affiliated task, then move all of the affiliated tasks
4026            // to the front and insert this new one.
4027            TaskRecord other = task.mNextAffiliate;
4028            if (other == null) {
4029                other = task.mPrevAffiliate;
4030            }
4031            if (other != null) {
4032                int otherIndex = mRecentTasks.indexOf(other);
4033                if (otherIndex >= 0) {
4034                    // Insert new task at appropriate location.
4035                    int taskIndex;
4036                    if (other == task.mNextAffiliate) {
4037                        // We found the index of our next affiliation, which is who is
4038                        // before us in the list, so add after that point.
4039                        taskIndex = otherIndex+1;
4040                    } else {
4041                        // We found the index of our previous affiliation, which is who is
4042                        // after us in the list, so add at their position.
4043                        taskIndex = otherIndex;
4044                    }
4045                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4046                            + taskIndex + ": " + task);
4047                    mRecentTasks.add(taskIndex, task);
4048
4049                    // Now move everything to the front.
4050                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4051                        // All went well.
4052                        return;
4053                    }
4054
4055                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4056                    // everything and then go through our general path of adding a new task.
4057                    needAffiliationFix = true;
4058                } else {
4059                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4060                            + other);
4061                    needAffiliationFix = true;
4062                }
4063            } else {
4064                if (DEBUG_RECENTS) Slog.d(TAG,
4065                        "addRecent: adding affiliated task without next/prev:" + task);
4066                needAffiliationFix = true;
4067            }
4068        }
4069        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4070
4071        if (needAffiliationFix) {
4072            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4073            cleanupRecentTasksLocked(task.userId);
4074        }
4075    }
4076
4077    /**
4078     * If needed, remove oldest existing entries in recents that are for the same kind
4079     * of task as the given one.
4080     */
4081    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4082        int N = mRecentTasks.size();
4083        final Intent intent = task.intent;
4084        final boolean document = intent != null && intent.isDocument();
4085
4086        int maxRecents = task.maxRecents - 1;
4087        for (int i=0; i<N; i++) {
4088            final TaskRecord tr = mRecentTasks.get(i);
4089            if (task != tr) {
4090                if (task.userId != tr.userId) {
4091                    continue;
4092                }
4093                if (i > MAX_RECENT_BITMAPS) {
4094                    tr.freeLastThumbnail();
4095                }
4096                final Intent trIntent = tr.intent;
4097                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4098                    (intent == null || !intent.filterEquals(trIntent))) {
4099                    continue;
4100                }
4101                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4102                if (document && trIsDocument) {
4103                    // These are the same document activity (not necessarily the same doc).
4104                    if (maxRecents > 0) {
4105                        --maxRecents;
4106                        continue;
4107                    }
4108                    // Hit the maximum number of documents for this task. Fall through
4109                    // and remove this document from recents.
4110                } else if (document || trIsDocument) {
4111                    // Only one of these is a document. Not the droid we're looking for.
4112                    continue;
4113                }
4114            }
4115
4116            if (!doTrim) {
4117                // If the caller is not actually asking for a trim, just tell them we reached
4118                // a point where the trim would happen.
4119                return i;
4120            }
4121
4122            // Either task and tr are the same or, their affinities match or their intents match
4123            // and neither of them is a document, or they are documents using the same activity
4124            // and their maxRecents has been reached.
4125            tr.disposeThumbnail();
4126            mRecentTasks.remove(i);
4127            if (task != tr) {
4128                tr.removedFromRecents(mTaskPersister);
4129            }
4130            i--;
4131            N--;
4132            if (task.intent == null) {
4133                // If the new recent task we are adding is not fully
4134                // specified, then replace it with the existing recent task.
4135                task = tr;
4136            }
4137            notifyTaskPersisterLocked(tr, false);
4138        }
4139
4140        return -1;
4141    }
4142
4143    @Override
4144    public void reportActivityFullyDrawn(IBinder token) {
4145        synchronized (this) {
4146            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4147            if (r == null) {
4148                return;
4149            }
4150            r.reportFullyDrawnLocked();
4151        }
4152    }
4153
4154    @Override
4155    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4156        synchronized (this) {
4157            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4158            if (r == null) {
4159                return;
4160            }
4161            final long origId = Binder.clearCallingIdentity();
4162            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4163            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4164                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4165            if (config != null) {
4166                r.frozenBeforeDestroy = true;
4167                if (!updateConfigurationLocked(config, r, false, false)) {
4168                    mStackSupervisor.resumeTopActivitiesLocked();
4169                }
4170            }
4171            Binder.restoreCallingIdentity(origId);
4172        }
4173    }
4174
4175    @Override
4176    public int getRequestedOrientation(IBinder token) {
4177        synchronized (this) {
4178            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4179            if (r == null) {
4180                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4181            }
4182            return mWindowManager.getAppOrientation(r.appToken);
4183        }
4184    }
4185
4186    /**
4187     * This is the internal entry point for handling Activity.finish().
4188     *
4189     * @param token The Binder token referencing the Activity we want to finish.
4190     * @param resultCode Result code, if any, from this Activity.
4191     * @param resultData Result data (Intent), if any, from this Activity.
4192     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4193     *            the root Activity in the task.
4194     *
4195     * @return Returns true if the activity successfully finished, or false if it is still running.
4196     */
4197    @Override
4198    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4199            boolean finishTask) {
4200        // Refuse possible leaked file descriptors
4201        if (resultData != null && resultData.hasFileDescriptors() == true) {
4202            throw new IllegalArgumentException("File descriptors passed in Intent");
4203        }
4204
4205        synchronized(this) {
4206            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4207            if (r == null) {
4208                return true;
4209            }
4210            // Keep track of the root activity of the task before we finish it
4211            TaskRecord tr = r.task;
4212            ActivityRecord rootR = tr.getRootActivity();
4213            if (rootR == null) {
4214                Slog.w(TAG, "Finishing task with all activities already finished");
4215            }
4216            // Do not allow task to finish in Lock Task mode.
4217            if (tr == mStackSupervisor.mLockTaskModeTask) {
4218                if (rootR == r) {
4219                    Slog.i(TAG, "Not finishing task in lock task mode");
4220                    mStackSupervisor.showLockTaskToast();
4221                    return false;
4222                }
4223            }
4224            if (mController != null) {
4225                // Find the first activity that is not finishing.
4226                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4227                if (next != null) {
4228                    // ask watcher if this is allowed
4229                    boolean resumeOK = true;
4230                    try {
4231                        resumeOK = mController.activityResuming(next.packageName);
4232                    } catch (RemoteException e) {
4233                        mController = null;
4234                        Watchdog.getInstance().setActivityController(null);
4235                    }
4236
4237                    if (!resumeOK) {
4238                        Slog.i(TAG, "Not finishing activity because controller resumed");
4239                        return false;
4240                    }
4241                }
4242            }
4243            final long origId = Binder.clearCallingIdentity();
4244            try {
4245                boolean res;
4246                if (finishTask && r == rootR) {
4247                    // If requested, remove the task that is associated to this activity only if it
4248                    // was the root activity in the task. The result code and data is ignored
4249                    // because we don't support returning them across task boundaries.
4250                    res = removeTaskByIdLocked(tr.taskId, false);
4251                    if (!res) {
4252                        Slog.i(TAG, "Removing task failed to finish activity");
4253                    }
4254                } else {
4255                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4256                            resultData, "app-request", true);
4257                    if (!res) {
4258                        Slog.i(TAG, "Failed to finish by app-request");
4259                    }
4260                }
4261                return res;
4262            } finally {
4263                Binder.restoreCallingIdentity(origId);
4264            }
4265        }
4266    }
4267
4268    @Override
4269    public final void finishHeavyWeightApp() {
4270        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4271                != PackageManager.PERMISSION_GRANTED) {
4272            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4273                    + Binder.getCallingPid()
4274                    + ", uid=" + Binder.getCallingUid()
4275                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4276            Slog.w(TAG, msg);
4277            throw new SecurityException(msg);
4278        }
4279
4280        synchronized(this) {
4281            if (mHeavyWeightProcess == null) {
4282                return;
4283            }
4284
4285            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4286                    mHeavyWeightProcess.activities);
4287            for (int i=0; i<activities.size(); i++) {
4288                ActivityRecord r = activities.get(i);
4289                if (!r.finishing) {
4290                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4291                            null, "finish-heavy", true);
4292                }
4293            }
4294
4295            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4296                    mHeavyWeightProcess.userId, 0));
4297            mHeavyWeightProcess = null;
4298        }
4299    }
4300
4301    @Override
4302    public void crashApplication(int uid, int initialPid, String packageName,
4303            String message) {
4304        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4305                != PackageManager.PERMISSION_GRANTED) {
4306            String msg = "Permission Denial: crashApplication() from pid="
4307                    + Binder.getCallingPid()
4308                    + ", uid=" + Binder.getCallingUid()
4309                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4310            Slog.w(TAG, msg);
4311            throw new SecurityException(msg);
4312        }
4313
4314        synchronized(this) {
4315            ProcessRecord proc = null;
4316
4317            // Figure out which process to kill.  We don't trust that initialPid
4318            // still has any relation to current pids, so must scan through the
4319            // list.
4320            synchronized (mPidsSelfLocked) {
4321                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4322                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4323                    if (p.uid != uid) {
4324                        continue;
4325                    }
4326                    if (p.pid == initialPid) {
4327                        proc = p;
4328                        break;
4329                    }
4330                    if (p.pkgList.containsKey(packageName)) {
4331                        proc = p;
4332                    }
4333                }
4334            }
4335
4336            if (proc == null) {
4337                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4338                        + " initialPid=" + initialPid
4339                        + " packageName=" + packageName);
4340                return;
4341            }
4342
4343            if (proc.thread != null) {
4344                if (proc.pid == Process.myPid()) {
4345                    Log.w(TAG, "crashApplication: trying to crash self!");
4346                    return;
4347                }
4348                long ident = Binder.clearCallingIdentity();
4349                try {
4350                    proc.thread.scheduleCrash(message);
4351                } catch (RemoteException e) {
4352                }
4353                Binder.restoreCallingIdentity(ident);
4354            }
4355        }
4356    }
4357
4358    @Override
4359    public final void finishSubActivity(IBinder token, String resultWho,
4360            int requestCode) {
4361        synchronized(this) {
4362            final long origId = Binder.clearCallingIdentity();
4363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4364            if (r != null) {
4365                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4366            }
4367            Binder.restoreCallingIdentity(origId);
4368        }
4369    }
4370
4371    @Override
4372    public boolean finishActivityAffinity(IBinder token) {
4373        synchronized(this) {
4374            final long origId = Binder.clearCallingIdentity();
4375            try {
4376                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4377
4378                ActivityRecord rootR = r.task.getRootActivity();
4379                // Do not allow task to finish in Lock Task mode.
4380                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4381                    if (rootR == r) {
4382                        mStackSupervisor.showLockTaskToast();
4383                        return false;
4384                    }
4385                }
4386                boolean res = false;
4387                if (r != null) {
4388                    res = r.task.stack.finishActivityAffinityLocked(r);
4389                }
4390                return res;
4391            } finally {
4392                Binder.restoreCallingIdentity(origId);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public void finishVoiceTask(IVoiceInteractionSession session) {
4399        synchronized(this) {
4400            final long origId = Binder.clearCallingIdentity();
4401            try {
4402                mStackSupervisor.finishVoiceTask(session);
4403            } finally {
4404                Binder.restoreCallingIdentity(origId);
4405            }
4406        }
4407
4408    }
4409
4410    @Override
4411    public boolean releaseActivityInstance(IBinder token) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416                if (r.task == null || r.task.stack == null) {
4417                    return false;
4418                }
4419                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4420            } finally {
4421                Binder.restoreCallingIdentity(origId);
4422            }
4423        }
4424    }
4425
4426    @Override
4427    public void releaseSomeActivities(IApplicationThread appInt) {
4428        synchronized(this) {
4429            final long origId = Binder.clearCallingIdentity();
4430            try {
4431                ProcessRecord app = getRecordForAppLocked(appInt);
4432                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4433            } finally {
4434                Binder.restoreCallingIdentity(origId);
4435            }
4436        }
4437    }
4438
4439    @Override
4440    public boolean willActivityBeVisible(IBinder token) {
4441        synchronized(this) {
4442            ActivityStack stack = ActivityRecord.getStackLocked(token);
4443            if (stack != null) {
4444                return stack.willActivityBeVisibleLocked(token);
4445            }
4446            return false;
4447        }
4448    }
4449
4450    @Override
4451    public void overridePendingTransition(IBinder token, String packageName,
4452            int enterAnim, int exitAnim) {
4453        synchronized(this) {
4454            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4455            if (self == null) {
4456                return;
4457            }
4458
4459            final long origId = Binder.clearCallingIdentity();
4460
4461            if (self.state == ActivityState.RESUMED
4462                    || self.state == ActivityState.PAUSING) {
4463                mWindowManager.overridePendingAppTransition(packageName,
4464                        enterAnim, exitAnim, null);
4465            }
4466
4467            Binder.restoreCallingIdentity(origId);
4468        }
4469    }
4470
4471    /**
4472     * Main function for removing an existing process from the activity manager
4473     * as a result of that process going away.  Clears out all connections
4474     * to the process.
4475     */
4476    private final void handleAppDiedLocked(ProcessRecord app,
4477            boolean restarting, boolean allowRestart) {
4478        int pid = app.pid;
4479        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4480        if (!kept && !restarting) {
4481            removeLruProcessLocked(app);
4482            if (pid > 0) {
4483                ProcessList.remove(pid);
4484            }
4485        }
4486
4487        if (mProfileProc == app) {
4488            clearProfilerLocked();
4489        }
4490
4491        // Remove this application's activities from active lists.
4492        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4493
4494        app.activities.clear();
4495
4496        if (app.instrumentationClass != null) {
4497            Slog.w(TAG, "Crash of app " + app.processName
4498                  + " running instrumentation " + app.instrumentationClass);
4499            Bundle info = new Bundle();
4500            info.putString("shortMsg", "Process crashed.");
4501            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4502        }
4503
4504        if (!restarting) {
4505            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4506                // If there was nothing to resume, and we are not already
4507                // restarting this process, but there is a visible activity that
4508                // is hosted by the process...  then make sure all visible
4509                // activities are running, taking care of restarting this
4510                // process.
4511                if (hasVisibleActivities) {
4512                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4513                }
4514            }
4515        }
4516    }
4517
4518    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4519        IBinder threadBinder = thread.asBinder();
4520        // Find the application record.
4521        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4522            ProcessRecord rec = mLruProcesses.get(i);
4523            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4524                return i;
4525            }
4526        }
4527        return -1;
4528    }
4529
4530    final ProcessRecord getRecordForAppLocked(
4531            IApplicationThread thread) {
4532        if (thread == null) {
4533            return null;
4534        }
4535
4536        int appIndex = getLRURecordIndexForAppLocked(thread);
4537        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4538    }
4539
4540    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4541        // If there are no longer any background processes running,
4542        // and the app that died was not running instrumentation,
4543        // then tell everyone we are now low on memory.
4544        boolean haveBg = false;
4545        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4546            ProcessRecord rec = mLruProcesses.get(i);
4547            if (rec.thread != null
4548                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4549                haveBg = true;
4550                break;
4551            }
4552        }
4553
4554        if (!haveBg) {
4555            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4556            if (doReport) {
4557                long now = SystemClock.uptimeMillis();
4558                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4559                    doReport = false;
4560                } else {
4561                    mLastMemUsageReportTime = now;
4562                }
4563            }
4564            final ArrayList<ProcessMemInfo> memInfos
4565                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4566            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4567            long now = SystemClock.uptimeMillis();
4568            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4569                ProcessRecord rec = mLruProcesses.get(i);
4570                if (rec == dyingProc || rec.thread == null) {
4571                    continue;
4572                }
4573                if (doReport) {
4574                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4575                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4576                }
4577                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4578                    // The low memory report is overriding any current
4579                    // state for a GC request.  Make sure to do
4580                    // heavy/important/visible/foreground processes first.
4581                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4582                        rec.lastRequestedGc = 0;
4583                    } else {
4584                        rec.lastRequestedGc = rec.lastLowMemory;
4585                    }
4586                    rec.reportLowMemory = true;
4587                    rec.lastLowMemory = now;
4588                    mProcessesToGc.remove(rec);
4589                    addProcessToGcListLocked(rec);
4590                }
4591            }
4592            if (doReport) {
4593                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4594                mHandler.sendMessage(msg);
4595            }
4596            scheduleAppGcsLocked();
4597        }
4598    }
4599
4600    final void appDiedLocked(ProcessRecord app) {
4601       appDiedLocked(app, app.pid, app.thread);
4602    }
4603
4604    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4605        // First check if this ProcessRecord is actually active for the pid.
4606        synchronized (mPidsSelfLocked) {
4607            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4608            if (curProc != app) {
4609                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4610                return;
4611            }
4612        }
4613
4614        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4615        synchronized (stats) {
4616            stats.noteProcessDiedLocked(app.info.uid, pid);
4617        }
4618
4619        Process.killProcessQuiet(pid);
4620        Process.killProcessGroup(app.info.uid, pid);
4621        app.killed = true;
4622
4623        // Clean up already done if the process has been re-started.
4624        if (app.pid == pid && app.thread != null &&
4625                app.thread.asBinder() == thread.asBinder()) {
4626            boolean doLowMem = app.instrumentationClass == null;
4627            boolean doOomAdj = doLowMem;
4628            if (!app.killedByAm) {
4629                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4630                        + ") has died");
4631                mAllowLowerMemLevel = true;
4632            } else {
4633                // Note that we always want to do oom adj to update our state with the
4634                // new number of procs.
4635                mAllowLowerMemLevel = false;
4636                doLowMem = false;
4637            }
4638            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4639            if (DEBUG_CLEANUP) Slog.v(
4640                TAG, "Dying app: " + app + ", pid: " + pid
4641                + ", thread: " + thread.asBinder());
4642            handleAppDiedLocked(app, false, true);
4643
4644            if (doOomAdj) {
4645                updateOomAdjLocked();
4646            }
4647            if (doLowMem) {
4648                doLowMemReportIfNeededLocked(app);
4649            }
4650        } else if (app.pid != pid) {
4651            // A new process has already been started.
4652            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4653                    + ") has died and restarted (pid " + app.pid + ").");
4654            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4655        } else if (DEBUG_PROCESSES) {
4656            Slog.d(TAG, "Received spurious death notification for thread "
4657                    + thread.asBinder());
4658        }
4659    }
4660
4661    /**
4662     * If a stack trace dump file is configured, dump process stack traces.
4663     * @param clearTraces causes the dump file to be erased prior to the new
4664     *    traces being written, if true; when false, the new traces will be
4665     *    appended to any existing file content.
4666     * @param firstPids of dalvik VM processes to dump stack traces for first
4667     * @param lastPids of dalvik VM processes to dump stack traces for last
4668     * @param nativeProcs optional list of native process names to dump stack crawls
4669     * @return file containing stack traces, or null if no dump file is configured
4670     */
4671    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4672            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4673        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4674        if (tracesPath == null || tracesPath.length() == 0) {
4675            return null;
4676        }
4677
4678        File tracesFile = new File(tracesPath);
4679        try {
4680            File tracesDir = tracesFile.getParentFile();
4681            if (!tracesDir.exists()) {
4682                tracesDir.mkdirs();
4683                if (!SELinux.restorecon(tracesDir)) {
4684                    return null;
4685                }
4686            }
4687            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4688
4689            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4690            tracesFile.createNewFile();
4691            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4692        } catch (IOException e) {
4693            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4694            return null;
4695        }
4696
4697        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4698        return tracesFile;
4699    }
4700
4701    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4702            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4703        // Use a FileObserver to detect when traces finish writing.
4704        // The order of traces is considered important to maintain for legibility.
4705        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4706            @Override
4707            public synchronized void onEvent(int event, String path) { notify(); }
4708        };
4709
4710        try {
4711            observer.startWatching();
4712
4713            // First collect all of the stacks of the most important pids.
4714            if (firstPids != null) {
4715                try {
4716                    int num = firstPids.size();
4717                    for (int i = 0; i < num; i++) {
4718                        synchronized (observer) {
4719                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4720                            observer.wait(200);  // Wait for write-close, give up after 200msec
4721                        }
4722                    }
4723                } catch (InterruptedException e) {
4724                    Slog.wtf(TAG, e);
4725                }
4726            }
4727
4728            // Next collect the stacks of the native pids
4729            if (nativeProcs != null) {
4730                int[] pids = Process.getPidsForCommands(nativeProcs);
4731                if (pids != null) {
4732                    for (int pid : pids) {
4733                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4734                    }
4735                }
4736            }
4737
4738            // Lastly, measure CPU usage.
4739            if (processCpuTracker != null) {
4740                processCpuTracker.init();
4741                System.gc();
4742                processCpuTracker.update();
4743                try {
4744                    synchronized (processCpuTracker) {
4745                        processCpuTracker.wait(500); // measure over 1/2 second.
4746                    }
4747                } catch (InterruptedException e) {
4748                }
4749                processCpuTracker.update();
4750
4751                // We'll take the stack crawls of just the top apps using CPU.
4752                final int N = processCpuTracker.countWorkingStats();
4753                int numProcs = 0;
4754                for (int i=0; i<N && numProcs<5; i++) {
4755                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4756                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4757                        numProcs++;
4758                        try {
4759                            synchronized (observer) {
4760                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4761                                observer.wait(200);  // Wait for write-close, give up after 200msec
4762                            }
4763                        } catch (InterruptedException e) {
4764                            Slog.wtf(TAG, e);
4765                        }
4766
4767                    }
4768                }
4769            }
4770        } finally {
4771            observer.stopWatching();
4772        }
4773    }
4774
4775    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4776        if (true || IS_USER_BUILD) {
4777            return;
4778        }
4779        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4780        if (tracesPath == null || tracesPath.length() == 0) {
4781            return;
4782        }
4783
4784        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4785        StrictMode.allowThreadDiskWrites();
4786        try {
4787            final File tracesFile = new File(tracesPath);
4788            final File tracesDir = tracesFile.getParentFile();
4789            final File tracesTmp = new File(tracesDir, "__tmp__");
4790            try {
4791                if (!tracesDir.exists()) {
4792                    tracesDir.mkdirs();
4793                    if (!SELinux.restorecon(tracesDir.getPath())) {
4794                        return;
4795                    }
4796                }
4797                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4798
4799                if (tracesFile.exists()) {
4800                    tracesTmp.delete();
4801                    tracesFile.renameTo(tracesTmp);
4802                }
4803                StringBuilder sb = new StringBuilder();
4804                Time tobj = new Time();
4805                tobj.set(System.currentTimeMillis());
4806                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4807                sb.append(": ");
4808                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4809                sb.append(" since ");
4810                sb.append(msg);
4811                FileOutputStream fos = new FileOutputStream(tracesFile);
4812                fos.write(sb.toString().getBytes());
4813                if (app == null) {
4814                    fos.write("\n*** No application process!".getBytes());
4815                }
4816                fos.close();
4817                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4818            } catch (IOException e) {
4819                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4820                return;
4821            }
4822
4823            if (app != null) {
4824                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4825                firstPids.add(app.pid);
4826                dumpStackTraces(tracesPath, firstPids, null, null, null);
4827            }
4828
4829            File lastTracesFile = null;
4830            File curTracesFile = null;
4831            for (int i=9; i>=0; i--) {
4832                String name = String.format(Locale.US, "slow%02d.txt", i);
4833                curTracesFile = new File(tracesDir, name);
4834                if (curTracesFile.exists()) {
4835                    if (lastTracesFile != null) {
4836                        curTracesFile.renameTo(lastTracesFile);
4837                    } else {
4838                        curTracesFile.delete();
4839                    }
4840                }
4841                lastTracesFile = curTracesFile;
4842            }
4843            tracesFile.renameTo(curTracesFile);
4844            if (tracesTmp.exists()) {
4845                tracesTmp.renameTo(tracesFile);
4846            }
4847        } finally {
4848            StrictMode.setThreadPolicy(oldPolicy);
4849        }
4850    }
4851
4852    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4853            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4854        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4855        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4856
4857        if (mController != null) {
4858            try {
4859                // 0 == continue, -1 = kill process immediately
4860                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4861                if (res < 0 && app.pid != MY_PID) {
4862                    app.kill("anr", true);
4863                }
4864            } catch (RemoteException e) {
4865                mController = null;
4866                Watchdog.getInstance().setActivityController(null);
4867            }
4868        }
4869
4870        long anrTime = SystemClock.uptimeMillis();
4871        if (MONITOR_CPU_USAGE) {
4872            updateCpuStatsNow();
4873        }
4874
4875        synchronized (this) {
4876            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4877            if (mShuttingDown) {
4878                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4879                return;
4880            } else if (app.notResponding) {
4881                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4882                return;
4883            } else if (app.crashing) {
4884                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4885                return;
4886            }
4887
4888            // In case we come through here for the same app before completing
4889            // this one, mark as anring now so we will bail out.
4890            app.notResponding = true;
4891
4892            // Log the ANR to the event log.
4893            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4894                    app.processName, app.info.flags, annotation);
4895
4896            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4897            firstPids.add(app.pid);
4898
4899            int parentPid = app.pid;
4900            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4901            if (parentPid != app.pid) firstPids.add(parentPid);
4902
4903            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4904
4905            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4906                ProcessRecord r = mLruProcesses.get(i);
4907                if (r != null && r.thread != null) {
4908                    int pid = r.pid;
4909                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4910                        if (r.persistent) {
4911                            firstPids.add(pid);
4912                        } else {
4913                            lastPids.put(pid, Boolean.TRUE);
4914                        }
4915                    }
4916                }
4917            }
4918        }
4919
4920        // Log the ANR to the main log.
4921        StringBuilder info = new StringBuilder();
4922        info.setLength(0);
4923        info.append("ANR in ").append(app.processName);
4924        if (activity != null && activity.shortComponentName != null) {
4925            info.append(" (").append(activity.shortComponentName).append(")");
4926        }
4927        info.append("\n");
4928        info.append("PID: ").append(app.pid).append("\n");
4929        if (annotation != null) {
4930            info.append("Reason: ").append(annotation).append("\n");
4931        }
4932        if (parent != null && parent != activity) {
4933            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4934        }
4935
4936        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4937
4938        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4939                NATIVE_STACKS_OF_INTEREST);
4940
4941        String cpuInfo = null;
4942        if (MONITOR_CPU_USAGE) {
4943            updateCpuStatsNow();
4944            synchronized (mProcessCpuTracker) {
4945                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4946            }
4947            info.append(processCpuTracker.printCurrentLoad());
4948            info.append(cpuInfo);
4949        }
4950
4951        info.append(processCpuTracker.printCurrentState(anrTime));
4952
4953        Slog.e(TAG, info.toString());
4954        if (tracesFile == null) {
4955            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4956            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4957        }
4958
4959        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4960                cpuInfo, tracesFile, null);
4961
4962        if (mController != null) {
4963            try {
4964                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4965                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4966                if (res != 0) {
4967                    if (res < 0 && app.pid != MY_PID) {
4968                        app.kill("anr", true);
4969                    } else {
4970                        synchronized (this) {
4971                            mServices.scheduleServiceTimeoutLocked(app);
4972                        }
4973                    }
4974                    return;
4975                }
4976            } catch (RemoteException e) {
4977                mController = null;
4978                Watchdog.getInstance().setActivityController(null);
4979            }
4980        }
4981
4982        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4983        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4984                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4985
4986        synchronized (this) {
4987            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4988                app.kill("bg anr", true);
4989                return;
4990            }
4991
4992            // Set the app's notResponding state, and look up the errorReportReceiver
4993            makeAppNotRespondingLocked(app,
4994                    activity != null ? activity.shortComponentName : null,
4995                    annotation != null ? "ANR " + annotation : "ANR",
4996                    info.toString());
4997
4998            // Bring up the infamous App Not Responding dialog
4999            Message msg = Message.obtain();
5000            HashMap<String, Object> map = new HashMap<String, Object>();
5001            msg.what = SHOW_NOT_RESPONDING_MSG;
5002            msg.obj = map;
5003            msg.arg1 = aboveSystem ? 1 : 0;
5004            map.put("app", app);
5005            if (activity != null) {
5006                map.put("activity", activity);
5007            }
5008
5009            mHandler.sendMessage(msg);
5010        }
5011    }
5012
5013    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5014        if (!mLaunchWarningShown) {
5015            mLaunchWarningShown = true;
5016            mHandler.post(new Runnable() {
5017                @Override
5018                public void run() {
5019                    synchronized (ActivityManagerService.this) {
5020                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5021                        d.show();
5022                        mHandler.postDelayed(new Runnable() {
5023                            @Override
5024                            public void run() {
5025                                synchronized (ActivityManagerService.this) {
5026                                    d.dismiss();
5027                                    mLaunchWarningShown = false;
5028                                }
5029                            }
5030                        }, 4000);
5031                    }
5032                }
5033            });
5034        }
5035    }
5036
5037    @Override
5038    public boolean clearApplicationUserData(final String packageName,
5039            final IPackageDataObserver observer, int userId) {
5040        enforceNotIsolatedCaller("clearApplicationUserData");
5041        int uid = Binder.getCallingUid();
5042        int pid = Binder.getCallingPid();
5043        userId = handleIncomingUser(pid, uid,
5044                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5045        long callingId = Binder.clearCallingIdentity();
5046        try {
5047            IPackageManager pm = AppGlobals.getPackageManager();
5048            int pkgUid = -1;
5049            synchronized(this) {
5050                try {
5051                    pkgUid = pm.getPackageUid(packageName, userId);
5052                } catch (RemoteException e) {
5053                }
5054                if (pkgUid == -1) {
5055                    Slog.w(TAG, "Invalid packageName: " + packageName);
5056                    if (observer != null) {
5057                        try {
5058                            observer.onRemoveCompleted(packageName, false);
5059                        } catch (RemoteException e) {
5060                            Slog.i(TAG, "Observer no longer exists.");
5061                        }
5062                    }
5063                    return false;
5064                }
5065                if (uid == pkgUid || checkComponentPermission(
5066                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5067                        pid, uid, -1, true)
5068                        == PackageManager.PERMISSION_GRANTED) {
5069                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5070                } else {
5071                    throw new SecurityException("PID " + pid + " does not have permission "
5072                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5073                                    + " of package " + packageName);
5074                }
5075
5076                // Remove all tasks match the cleared application package and user
5077                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5078                    final TaskRecord tr = mRecentTasks.get(i);
5079                    final String taskPackageName =
5080                            tr.getBaseIntent().getComponent().getPackageName();
5081                    if (tr.userId != userId) continue;
5082                    if (!taskPackageName.equals(packageName)) continue;
5083                    removeTaskByIdLocked(tr.taskId, false);
5084                }
5085            }
5086
5087            try {
5088                // Clear application user data
5089                pm.clearApplicationUserData(packageName, observer, userId);
5090
5091                synchronized(this) {
5092                    // Remove all permissions granted from/to this package
5093                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5094                }
5095
5096                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5097                        Uri.fromParts("package", packageName, null));
5098                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5099                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5100                        null, null, 0, null, null, null, false, false, userId);
5101            } catch (RemoteException e) {
5102            }
5103        } finally {
5104            Binder.restoreCallingIdentity(callingId);
5105        }
5106        return true;
5107    }
5108
5109    @Override
5110    public void killBackgroundProcesses(final String packageName, int userId) {
5111        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5112                != PackageManager.PERMISSION_GRANTED &&
5113                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5114                        != PackageManager.PERMISSION_GRANTED) {
5115            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5116                    + Binder.getCallingPid()
5117                    + ", uid=" + Binder.getCallingUid()
5118                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5119            Slog.w(TAG, msg);
5120            throw new SecurityException(msg);
5121        }
5122
5123        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5124                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5125        long callingId = Binder.clearCallingIdentity();
5126        try {
5127            IPackageManager pm = AppGlobals.getPackageManager();
5128            synchronized(this) {
5129                int appId = -1;
5130                try {
5131                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5132                } catch (RemoteException e) {
5133                }
5134                if (appId == -1) {
5135                    Slog.w(TAG, "Invalid packageName: " + packageName);
5136                    return;
5137                }
5138                killPackageProcessesLocked(packageName, appId, userId,
5139                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5140            }
5141        } finally {
5142            Binder.restoreCallingIdentity(callingId);
5143        }
5144    }
5145
5146    @Override
5147    public void killAllBackgroundProcesses() {
5148        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5149                != PackageManager.PERMISSION_GRANTED) {
5150            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5151                    + Binder.getCallingPid()
5152                    + ", uid=" + Binder.getCallingUid()
5153                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5154            Slog.w(TAG, msg);
5155            throw new SecurityException(msg);
5156        }
5157
5158        long callingId = Binder.clearCallingIdentity();
5159        try {
5160            synchronized(this) {
5161                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5162                final int NP = mProcessNames.getMap().size();
5163                for (int ip=0; ip<NP; ip++) {
5164                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5165                    final int NA = apps.size();
5166                    for (int ia=0; ia<NA; ia++) {
5167                        ProcessRecord app = apps.valueAt(ia);
5168                        if (app.persistent) {
5169                            // we don't kill persistent processes
5170                            continue;
5171                        }
5172                        if (app.removed) {
5173                            procs.add(app);
5174                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5175                            app.removed = true;
5176                            procs.add(app);
5177                        }
5178                    }
5179                }
5180
5181                int N = procs.size();
5182                for (int i=0; i<N; i++) {
5183                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5184                }
5185                mAllowLowerMemLevel = true;
5186                updateOomAdjLocked();
5187                doLowMemReportIfNeededLocked(null);
5188            }
5189        } finally {
5190            Binder.restoreCallingIdentity(callingId);
5191        }
5192    }
5193
5194    @Override
5195    public void forceStopPackage(final String packageName, int userId) {
5196        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5197                != PackageManager.PERMISSION_GRANTED) {
5198            String msg = "Permission Denial: forceStopPackage() from pid="
5199                    + Binder.getCallingPid()
5200                    + ", uid=" + Binder.getCallingUid()
5201                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5202            Slog.w(TAG, msg);
5203            throw new SecurityException(msg);
5204        }
5205        final int callingPid = Binder.getCallingPid();
5206        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5207                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5208        long callingId = Binder.clearCallingIdentity();
5209        try {
5210            IPackageManager pm = AppGlobals.getPackageManager();
5211            synchronized(this) {
5212                int[] users = userId == UserHandle.USER_ALL
5213                        ? getUsersLocked() : new int[] { userId };
5214                for (int user : users) {
5215                    int pkgUid = -1;
5216                    try {
5217                        pkgUid = pm.getPackageUid(packageName, user);
5218                    } catch (RemoteException e) {
5219                    }
5220                    if (pkgUid == -1) {
5221                        Slog.w(TAG, "Invalid packageName: " + packageName);
5222                        continue;
5223                    }
5224                    try {
5225                        pm.setPackageStoppedState(packageName, true, user);
5226                    } catch (RemoteException e) {
5227                    } catch (IllegalArgumentException e) {
5228                        Slog.w(TAG, "Failed trying to unstop package "
5229                                + packageName + ": " + e);
5230                    }
5231                    if (isUserRunningLocked(user, false)) {
5232                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5233                    }
5234                }
5235            }
5236        } finally {
5237            Binder.restoreCallingIdentity(callingId);
5238        }
5239    }
5240
5241    @Override
5242    public void addPackageDependency(String packageName) {
5243        synchronized (this) {
5244            int callingPid = Binder.getCallingPid();
5245            if (callingPid == Process.myPid()) {
5246                //  Yeah, um, no.
5247                Slog.w(TAG, "Can't addPackageDependency on system process");
5248                return;
5249            }
5250            ProcessRecord proc;
5251            synchronized (mPidsSelfLocked) {
5252                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5253            }
5254            if (proc != null) {
5255                if (proc.pkgDeps == null) {
5256                    proc.pkgDeps = new ArraySet<String>(1);
5257                }
5258                proc.pkgDeps.add(packageName);
5259            }
5260        }
5261    }
5262
5263    /*
5264     * The pkg name and app id have to be specified.
5265     */
5266    @Override
5267    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5268        if (pkg == null) {
5269            return;
5270        }
5271        // Make sure the uid is valid.
5272        if (appid < 0) {
5273            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5274            return;
5275        }
5276        int callerUid = Binder.getCallingUid();
5277        // Only the system server can kill an application
5278        if (callerUid == Process.SYSTEM_UID) {
5279            // Post an aysnc message to kill the application
5280            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5281            msg.arg1 = appid;
5282            msg.arg2 = 0;
5283            Bundle bundle = new Bundle();
5284            bundle.putString("pkg", pkg);
5285            bundle.putString("reason", reason);
5286            msg.obj = bundle;
5287            mHandler.sendMessage(msg);
5288        } else {
5289            throw new SecurityException(callerUid + " cannot kill pkg: " +
5290                    pkg);
5291        }
5292    }
5293
5294    @Override
5295    public void closeSystemDialogs(String reason) {
5296        enforceNotIsolatedCaller("closeSystemDialogs");
5297
5298        final int pid = Binder.getCallingPid();
5299        final int uid = Binder.getCallingUid();
5300        final long origId = Binder.clearCallingIdentity();
5301        try {
5302            synchronized (this) {
5303                // Only allow this from foreground processes, so that background
5304                // applications can't abuse it to prevent system UI from being shown.
5305                if (uid >= Process.FIRST_APPLICATION_UID) {
5306                    ProcessRecord proc;
5307                    synchronized (mPidsSelfLocked) {
5308                        proc = mPidsSelfLocked.get(pid);
5309                    }
5310                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5311                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5312                                + " from background process " + proc);
5313                        return;
5314                    }
5315                }
5316                closeSystemDialogsLocked(reason);
5317            }
5318        } finally {
5319            Binder.restoreCallingIdentity(origId);
5320        }
5321    }
5322
5323    void closeSystemDialogsLocked(String reason) {
5324        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5325        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5326                | Intent.FLAG_RECEIVER_FOREGROUND);
5327        if (reason != null) {
5328            intent.putExtra("reason", reason);
5329        }
5330        mWindowManager.closeSystemDialogs(reason);
5331
5332        mStackSupervisor.closeSystemDialogsLocked();
5333
5334        broadcastIntentLocked(null, null, intent, null,
5335                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5336                Process.SYSTEM_UID, UserHandle.USER_ALL);
5337    }
5338
5339    @Override
5340    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5341        enforceNotIsolatedCaller("getProcessMemoryInfo");
5342        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5343        for (int i=pids.length-1; i>=0; i--) {
5344            ProcessRecord proc;
5345            int oomAdj;
5346            synchronized (this) {
5347                synchronized (mPidsSelfLocked) {
5348                    proc = mPidsSelfLocked.get(pids[i]);
5349                    oomAdj = proc != null ? proc.setAdj : 0;
5350                }
5351            }
5352            infos[i] = new Debug.MemoryInfo();
5353            Debug.getMemoryInfo(pids[i], infos[i]);
5354            if (proc != null) {
5355                synchronized (this) {
5356                    if (proc.thread != null && proc.setAdj == oomAdj) {
5357                        // Record this for posterity if the process has been stable.
5358                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5359                                infos[i].getTotalUss(), false, proc.pkgList);
5360                    }
5361                }
5362            }
5363        }
5364        return infos;
5365    }
5366
5367    @Override
5368    public long[] getProcessPss(int[] pids) {
5369        enforceNotIsolatedCaller("getProcessPss");
5370        long[] pss = new long[pids.length];
5371        for (int i=pids.length-1; i>=0; i--) {
5372            ProcessRecord proc;
5373            int oomAdj;
5374            synchronized (this) {
5375                synchronized (mPidsSelfLocked) {
5376                    proc = mPidsSelfLocked.get(pids[i]);
5377                    oomAdj = proc != null ? proc.setAdj : 0;
5378                }
5379            }
5380            long[] tmpUss = new long[1];
5381            pss[i] = Debug.getPss(pids[i], tmpUss);
5382            if (proc != null) {
5383                synchronized (this) {
5384                    if (proc.thread != null && proc.setAdj == oomAdj) {
5385                        // Record this for posterity if the process has been stable.
5386                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5387                    }
5388                }
5389            }
5390        }
5391        return pss;
5392    }
5393
5394    @Override
5395    public void killApplicationProcess(String processName, int uid) {
5396        if (processName == null) {
5397            return;
5398        }
5399
5400        int callerUid = Binder.getCallingUid();
5401        // Only the system server can kill an application
5402        if (callerUid == Process.SYSTEM_UID) {
5403            synchronized (this) {
5404                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5405                if (app != null && app.thread != null) {
5406                    try {
5407                        app.thread.scheduleSuicide();
5408                    } catch (RemoteException e) {
5409                        // If the other end already died, then our work here is done.
5410                    }
5411                } else {
5412                    Slog.w(TAG, "Process/uid not found attempting kill of "
5413                            + processName + " / " + uid);
5414                }
5415            }
5416        } else {
5417            throw new SecurityException(callerUid + " cannot kill app process: " +
5418                    processName);
5419        }
5420    }
5421
5422    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5423        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5424                false, true, false, false, UserHandle.getUserId(uid), reason);
5425        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5426                Uri.fromParts("package", packageName, null));
5427        if (!mProcessesReady) {
5428            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5429                    | Intent.FLAG_RECEIVER_FOREGROUND);
5430        }
5431        intent.putExtra(Intent.EXTRA_UID, uid);
5432        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5433        broadcastIntentLocked(null, null, intent,
5434                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5435                false, false,
5436                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5437    }
5438
5439    private void forceStopUserLocked(int userId, String reason) {
5440        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5441        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5442        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5443                | Intent.FLAG_RECEIVER_FOREGROUND);
5444        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5445        broadcastIntentLocked(null, null, intent,
5446                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5447                false, false,
5448                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5449    }
5450
5451    private final boolean killPackageProcessesLocked(String packageName, int appId,
5452            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5453            boolean doit, boolean evenPersistent, String reason) {
5454        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5455
5456        // Remove all processes this package may have touched: all with the
5457        // same UID (except for the system or root user), and all whose name
5458        // matches the package name.
5459        final int NP = mProcessNames.getMap().size();
5460        for (int ip=0; ip<NP; ip++) {
5461            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5462            final int NA = apps.size();
5463            for (int ia=0; ia<NA; ia++) {
5464                ProcessRecord app = apps.valueAt(ia);
5465                if (app.persistent && !evenPersistent) {
5466                    // we don't kill persistent processes
5467                    continue;
5468                }
5469                if (app.removed) {
5470                    if (doit) {
5471                        procs.add(app);
5472                    }
5473                    continue;
5474                }
5475
5476                // Skip process if it doesn't meet our oom adj requirement.
5477                if (app.setAdj < minOomAdj) {
5478                    continue;
5479                }
5480
5481                // If no package is specified, we call all processes under the
5482                // give user id.
5483                if (packageName == null) {
5484                    if (app.userId != userId) {
5485                        continue;
5486                    }
5487                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5488                        continue;
5489                    }
5490                // Package has been specified, we want to hit all processes
5491                // that match it.  We need to qualify this by the processes
5492                // that are running under the specified app and user ID.
5493                } else {
5494                    final boolean isDep = app.pkgDeps != null
5495                            && app.pkgDeps.contains(packageName);
5496                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5497                        continue;
5498                    }
5499                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5500                        continue;
5501                    }
5502                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5503                        continue;
5504                    }
5505                }
5506
5507                // Process has passed all conditions, kill it!
5508                if (!doit) {
5509                    return true;
5510                }
5511                app.removed = true;
5512                procs.add(app);
5513            }
5514        }
5515
5516        int N = procs.size();
5517        for (int i=0; i<N; i++) {
5518            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5519        }
5520        updateOomAdjLocked();
5521        return N > 0;
5522    }
5523
5524    private final boolean forceStopPackageLocked(String name, int appId,
5525            boolean callerWillRestart, boolean purgeCache, boolean doit,
5526            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5527        int i;
5528        int N;
5529
5530        if (userId == UserHandle.USER_ALL && name == null) {
5531            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5532        }
5533
5534        if (appId < 0 && name != null) {
5535            try {
5536                appId = UserHandle.getAppId(
5537                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5538            } catch (RemoteException e) {
5539            }
5540        }
5541
5542        if (doit) {
5543            if (name != null) {
5544                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5545                        + " user=" + userId + ": " + reason);
5546            } else {
5547                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5548            }
5549
5550            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5551            for (int ip=pmap.size()-1; ip>=0; ip--) {
5552                SparseArray<Long> ba = pmap.valueAt(ip);
5553                for (i=ba.size()-1; i>=0; i--) {
5554                    boolean remove = false;
5555                    final int entUid = ba.keyAt(i);
5556                    if (name != null) {
5557                        if (userId == UserHandle.USER_ALL) {
5558                            if (UserHandle.getAppId(entUid) == appId) {
5559                                remove = true;
5560                            }
5561                        } else {
5562                            if (entUid == UserHandle.getUid(userId, appId)) {
5563                                remove = true;
5564                            }
5565                        }
5566                    } else if (UserHandle.getUserId(entUid) == userId) {
5567                        remove = true;
5568                    }
5569                    if (remove) {
5570                        ba.removeAt(i);
5571                    }
5572                }
5573                if (ba.size() == 0) {
5574                    pmap.removeAt(ip);
5575                }
5576            }
5577        }
5578
5579        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5580                -100, callerWillRestart, true, doit, evenPersistent,
5581                name == null ? ("stop user " + userId) : ("stop " + name));
5582
5583        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5584            if (!doit) {
5585                return true;
5586            }
5587            didSomething = true;
5588        }
5589
5590        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5591            if (!doit) {
5592                return true;
5593            }
5594            didSomething = true;
5595        }
5596
5597        if (name == null) {
5598            // Remove all sticky broadcasts from this user.
5599            mStickyBroadcasts.remove(userId);
5600        }
5601
5602        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5603        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5604                userId, providers)) {
5605            if (!doit) {
5606                return true;
5607            }
5608            didSomething = true;
5609        }
5610        N = providers.size();
5611        for (i=0; i<N; i++) {
5612            removeDyingProviderLocked(null, providers.get(i), true);
5613        }
5614
5615        // Remove transient permissions granted from/to this package/user
5616        removeUriPermissionsForPackageLocked(name, userId, false);
5617
5618        if (name == null || uninstalling) {
5619            // Remove pending intents.  For now we only do this when force
5620            // stopping users, because we have some problems when doing this
5621            // for packages -- app widgets are not currently cleaned up for
5622            // such packages, so they can be left with bad pending intents.
5623            if (mIntentSenderRecords.size() > 0) {
5624                Iterator<WeakReference<PendingIntentRecord>> it
5625                        = mIntentSenderRecords.values().iterator();
5626                while (it.hasNext()) {
5627                    WeakReference<PendingIntentRecord> wpir = it.next();
5628                    if (wpir == null) {
5629                        it.remove();
5630                        continue;
5631                    }
5632                    PendingIntentRecord pir = wpir.get();
5633                    if (pir == null) {
5634                        it.remove();
5635                        continue;
5636                    }
5637                    if (name == null) {
5638                        // Stopping user, remove all objects for the user.
5639                        if (pir.key.userId != userId) {
5640                            // Not the same user, skip it.
5641                            continue;
5642                        }
5643                    } else {
5644                        if (UserHandle.getAppId(pir.uid) != appId) {
5645                            // Different app id, skip it.
5646                            continue;
5647                        }
5648                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5649                            // Different user, skip it.
5650                            continue;
5651                        }
5652                        if (!pir.key.packageName.equals(name)) {
5653                            // Different package, skip it.
5654                            continue;
5655                        }
5656                    }
5657                    if (!doit) {
5658                        return true;
5659                    }
5660                    didSomething = true;
5661                    it.remove();
5662                    pir.canceled = true;
5663                    if (pir.key.activity != null) {
5664                        pir.key.activity.pendingResults.remove(pir.ref);
5665                    }
5666                }
5667            }
5668        }
5669
5670        if (doit) {
5671            if (purgeCache && name != null) {
5672                AttributeCache ac = AttributeCache.instance();
5673                if (ac != null) {
5674                    ac.removePackage(name);
5675                }
5676            }
5677            if (mBooted) {
5678                mStackSupervisor.resumeTopActivitiesLocked();
5679                mStackSupervisor.scheduleIdleLocked();
5680            }
5681        }
5682
5683        return didSomething;
5684    }
5685
5686    private final boolean removeProcessLocked(ProcessRecord app,
5687            boolean callerWillRestart, boolean allowRestart, String reason) {
5688        final String name = app.processName;
5689        final int uid = app.uid;
5690        if (DEBUG_PROCESSES) Slog.d(
5691            TAG, "Force removing proc " + app.toShortString() + " (" + name
5692            + "/" + uid + ")");
5693
5694        mProcessNames.remove(name, uid);
5695        mIsolatedProcesses.remove(app.uid);
5696        if (mHeavyWeightProcess == app) {
5697            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5698                    mHeavyWeightProcess.userId, 0));
5699            mHeavyWeightProcess = null;
5700        }
5701        boolean needRestart = false;
5702        if (app.pid > 0 && app.pid != MY_PID) {
5703            int pid = app.pid;
5704            synchronized (mPidsSelfLocked) {
5705                mPidsSelfLocked.remove(pid);
5706                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5707            }
5708            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5709            if (app.isolated) {
5710                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5711            }
5712            app.kill(reason, true);
5713            handleAppDiedLocked(app, true, allowRestart);
5714            removeLruProcessLocked(app);
5715
5716            if (app.persistent && !app.isolated) {
5717                if (!callerWillRestart) {
5718                    addAppLocked(app.info, false, null /* ABI override */);
5719                } else {
5720                    needRestart = true;
5721                }
5722            }
5723        } else {
5724            mRemovedProcesses.add(app);
5725        }
5726
5727        return needRestart;
5728    }
5729
5730    private final void processStartTimedOutLocked(ProcessRecord app) {
5731        final int pid = app.pid;
5732        boolean gone = false;
5733        synchronized (mPidsSelfLocked) {
5734            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5735            if (knownApp != null && knownApp.thread == null) {
5736                mPidsSelfLocked.remove(pid);
5737                gone = true;
5738            }
5739        }
5740
5741        if (gone) {
5742            Slog.w(TAG, "Process " + app + " failed to attach");
5743            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5744                    pid, app.uid, app.processName);
5745            mProcessNames.remove(app.processName, app.uid);
5746            mIsolatedProcesses.remove(app.uid);
5747            if (mHeavyWeightProcess == app) {
5748                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5749                        mHeavyWeightProcess.userId, 0));
5750                mHeavyWeightProcess = null;
5751            }
5752            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5753            if (app.isolated) {
5754                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5755            }
5756            // Take care of any launching providers waiting for this process.
5757            checkAppInLaunchingProvidersLocked(app, true);
5758            // Take care of any services that are waiting for the process.
5759            mServices.processStartTimedOutLocked(app);
5760            app.kill("start timeout", true);
5761            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5762                Slog.w(TAG, "Unattached app died before backup, skipping");
5763                try {
5764                    IBackupManager bm = IBackupManager.Stub.asInterface(
5765                            ServiceManager.getService(Context.BACKUP_SERVICE));
5766                    bm.agentDisconnected(app.info.packageName);
5767                } catch (RemoteException e) {
5768                    // Can't happen; the backup manager is local
5769                }
5770            }
5771            if (isPendingBroadcastProcessLocked(pid)) {
5772                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5773                skipPendingBroadcastLocked(pid);
5774            }
5775        } else {
5776            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5777        }
5778    }
5779
5780    private final boolean attachApplicationLocked(IApplicationThread thread,
5781            int pid) {
5782
5783        // Find the application record that is being attached...  either via
5784        // the pid if we are running in multiple processes, or just pull the
5785        // next app record if we are emulating process with anonymous threads.
5786        ProcessRecord app;
5787        if (pid != MY_PID && pid >= 0) {
5788            synchronized (mPidsSelfLocked) {
5789                app = mPidsSelfLocked.get(pid);
5790            }
5791        } else {
5792            app = null;
5793        }
5794
5795        if (app == null) {
5796            Slog.w(TAG, "No pending application record for pid " + pid
5797                    + " (IApplicationThread " + thread + "); dropping process");
5798            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5799            if (pid > 0 && pid != MY_PID) {
5800                Process.killProcessQuiet(pid);
5801                //TODO: Process.killProcessGroup(app.info.uid, pid);
5802            } else {
5803                try {
5804                    thread.scheduleExit();
5805                } catch (Exception e) {
5806                    // Ignore exceptions.
5807                }
5808            }
5809            return false;
5810        }
5811
5812        // If this application record is still attached to a previous
5813        // process, clean it up now.
5814        if (app.thread != null) {
5815            handleAppDiedLocked(app, true, true);
5816        }
5817
5818        // Tell the process all about itself.
5819
5820        if (localLOGV) Slog.v(
5821                TAG, "Binding process pid " + pid + " to record " + app);
5822
5823        final String processName = app.processName;
5824        try {
5825            AppDeathRecipient adr = new AppDeathRecipient(
5826                    app, pid, thread);
5827            thread.asBinder().linkToDeath(adr, 0);
5828            app.deathRecipient = adr;
5829        } catch (RemoteException e) {
5830            app.resetPackageList(mProcessStats);
5831            startProcessLocked(app, "link fail", processName);
5832            return false;
5833        }
5834
5835        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5836
5837        app.makeActive(thread, mProcessStats);
5838        app.curAdj = app.setAdj = -100;
5839        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5840        app.forcingToForeground = null;
5841        updateProcessForegroundLocked(app, false, false);
5842        app.hasShownUi = false;
5843        app.debugging = false;
5844        app.cached = false;
5845
5846        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5847
5848        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5849        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5850
5851        if (!normalMode) {
5852            Slog.i(TAG, "Launching preboot mode app: " + app);
5853        }
5854
5855        if (localLOGV) Slog.v(
5856            TAG, "New app record " + app
5857            + " thread=" + thread.asBinder() + " pid=" + pid);
5858        try {
5859            int testMode = IApplicationThread.DEBUG_OFF;
5860            if (mDebugApp != null && mDebugApp.equals(processName)) {
5861                testMode = mWaitForDebugger
5862                    ? IApplicationThread.DEBUG_WAIT
5863                    : IApplicationThread.DEBUG_ON;
5864                app.debugging = true;
5865                if (mDebugTransient) {
5866                    mDebugApp = mOrigDebugApp;
5867                    mWaitForDebugger = mOrigWaitForDebugger;
5868                }
5869            }
5870            String profileFile = app.instrumentationProfileFile;
5871            ParcelFileDescriptor profileFd = null;
5872            int samplingInterval = 0;
5873            boolean profileAutoStop = false;
5874            if (mProfileApp != null && mProfileApp.equals(processName)) {
5875                mProfileProc = app;
5876                profileFile = mProfileFile;
5877                profileFd = mProfileFd;
5878                samplingInterval = mSamplingInterval;
5879                profileAutoStop = mAutoStopProfiler;
5880            }
5881            boolean enableOpenGlTrace = false;
5882            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5883                enableOpenGlTrace = true;
5884                mOpenGlTraceApp = null;
5885            }
5886
5887            // If the app is being launched for restore or full backup, set it up specially
5888            boolean isRestrictedBackupMode = false;
5889            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5890                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5891                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5892                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5893            }
5894
5895            ensurePackageDexOpt(app.instrumentationInfo != null
5896                    ? app.instrumentationInfo.packageName
5897                    : app.info.packageName);
5898            if (app.instrumentationClass != null) {
5899                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5900            }
5901            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5902                    + processName + " with config " + mConfiguration);
5903            ApplicationInfo appInfo = app.instrumentationInfo != null
5904                    ? app.instrumentationInfo : app.info;
5905            app.compat = compatibilityInfoForPackageLocked(appInfo);
5906            if (profileFd != null) {
5907                profileFd = profileFd.dup();
5908            }
5909            ProfilerInfo profilerInfo = profileFile == null ? null
5910                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5911            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5912                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5913                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5914                    isRestrictedBackupMode || !normalMode, app.persistent,
5915                    new Configuration(mConfiguration), app.compat,
5916                    getCommonServicesLocked(app.isolated),
5917                    mCoreSettingsObserver.getCoreSettingsLocked());
5918            updateLruProcessLocked(app, false, null);
5919            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5920        } catch (Exception e) {
5921            // todo: Yikes!  What should we do?  For now we will try to
5922            // start another process, but that could easily get us in
5923            // an infinite loop of restarting processes...
5924            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5925
5926            app.resetPackageList(mProcessStats);
5927            app.unlinkDeathRecipient();
5928            startProcessLocked(app, "bind fail", processName);
5929            return false;
5930        }
5931
5932        // Remove this record from the list of starting applications.
5933        mPersistentStartingProcesses.remove(app);
5934        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5935                "Attach application locked removing on hold: " + app);
5936        mProcessesOnHold.remove(app);
5937
5938        boolean badApp = false;
5939        boolean didSomething = false;
5940
5941        // See if the top visible activity is waiting to run in this process...
5942        if (normalMode) {
5943            try {
5944                if (mStackSupervisor.attachApplicationLocked(app)) {
5945                    didSomething = true;
5946                }
5947            } catch (Exception e) {
5948                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5949                badApp = true;
5950            }
5951        }
5952
5953        // Find any services that should be running in this process...
5954        if (!badApp) {
5955            try {
5956                didSomething |= mServices.attachApplicationLocked(app, processName);
5957            } catch (Exception e) {
5958                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5959                badApp = true;
5960            }
5961        }
5962
5963        // Check if a next-broadcast receiver is in this process...
5964        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5965            try {
5966                didSomething |= sendPendingBroadcastsLocked(app);
5967            } catch (Exception e) {
5968                // If the app died trying to launch the receiver we declare it 'bad'
5969                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5970                badApp = true;
5971            }
5972        }
5973
5974        // Check whether the next backup agent is in this process...
5975        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5976            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5977            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5978            try {
5979                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5980                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5981                        mBackupTarget.backupMode);
5982            } catch (Exception e) {
5983                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5984                badApp = true;
5985            }
5986        }
5987
5988        if (badApp) {
5989            app.kill("error during init", true);
5990            handleAppDiedLocked(app, false, true);
5991            return false;
5992        }
5993
5994        if (!didSomething) {
5995            updateOomAdjLocked();
5996        }
5997
5998        return true;
5999    }
6000
6001    @Override
6002    public final void attachApplication(IApplicationThread thread) {
6003        synchronized (this) {
6004            int callingPid = Binder.getCallingPid();
6005            final long origId = Binder.clearCallingIdentity();
6006            attachApplicationLocked(thread, callingPid);
6007            Binder.restoreCallingIdentity(origId);
6008        }
6009    }
6010
6011    @Override
6012    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6013        final long origId = Binder.clearCallingIdentity();
6014        synchronized (this) {
6015            ActivityStack stack = ActivityRecord.getStackLocked(token);
6016            if (stack != null) {
6017                ActivityRecord r =
6018                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6019                if (stopProfiling) {
6020                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6021                        try {
6022                            mProfileFd.close();
6023                        } catch (IOException e) {
6024                        }
6025                        clearProfilerLocked();
6026                    }
6027                }
6028            }
6029        }
6030        Binder.restoreCallingIdentity(origId);
6031    }
6032
6033    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6034        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6035                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6036    }
6037
6038    void enableScreenAfterBoot() {
6039        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6040                SystemClock.uptimeMillis());
6041        mWindowManager.enableScreenAfterBoot();
6042
6043        synchronized (this) {
6044            updateEventDispatchingLocked();
6045        }
6046    }
6047
6048    @Override
6049    public void showBootMessage(final CharSequence msg, final boolean always) {
6050        enforceNotIsolatedCaller("showBootMessage");
6051        mWindowManager.showBootMessage(msg, always);
6052    }
6053
6054    @Override
6055    public void keyguardWaitingForActivityDrawn() {
6056        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6057        final long token = Binder.clearCallingIdentity();
6058        try {
6059            synchronized (this) {
6060                if (DEBUG_LOCKSCREEN) logLockScreen("");
6061                mWindowManager.keyguardWaitingForActivityDrawn();
6062                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6063                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6064                }
6065            }
6066        } finally {
6067            Binder.restoreCallingIdentity(token);
6068        }
6069    }
6070
6071    final void finishBooting() {
6072        synchronized (this) {
6073            if (!mBootAnimationComplete) {
6074                mCallFinishBooting = true;
6075                return;
6076            }
6077            mCallFinishBooting = false;
6078        }
6079
6080        ArraySet<String> completedIsas = new ArraySet<String>();
6081        for (String abi : Build.SUPPORTED_ABIS) {
6082            Process.establishZygoteConnectionForAbi(abi);
6083            final String instructionSet = VMRuntime.getInstructionSet(abi);
6084            if (!completedIsas.contains(instructionSet)) {
6085                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6086                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6087                }
6088                completedIsas.add(instructionSet);
6089            }
6090        }
6091
6092        IntentFilter pkgFilter = new IntentFilter();
6093        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6094        pkgFilter.addDataScheme("package");
6095        mContext.registerReceiver(new BroadcastReceiver() {
6096            @Override
6097            public void onReceive(Context context, Intent intent) {
6098                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6099                if (pkgs != null) {
6100                    for (String pkg : pkgs) {
6101                        synchronized (ActivityManagerService.this) {
6102                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6103                                    0, "finished booting")) {
6104                                setResultCode(Activity.RESULT_OK);
6105                                return;
6106                            }
6107                        }
6108                    }
6109                }
6110            }
6111        }, pkgFilter);
6112
6113        // Let system services know.
6114        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6115
6116        synchronized (this) {
6117            // Ensure that any processes we had put on hold are now started
6118            // up.
6119            final int NP = mProcessesOnHold.size();
6120            if (NP > 0) {
6121                ArrayList<ProcessRecord> procs =
6122                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6123                for (int ip=0; ip<NP; ip++) {
6124                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6125                            + procs.get(ip));
6126                    startProcessLocked(procs.get(ip), "on-hold", null);
6127                }
6128            }
6129
6130            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6131                // Start looking for apps that are abusing wake locks.
6132                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6133                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6134                // Tell anyone interested that we are done booting!
6135                SystemProperties.set("sys.boot_completed", "1");
6136
6137                // And trigger dev.bootcomplete if we are not showing encryption progress
6138                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6139                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6140                    SystemProperties.set("dev.bootcomplete", "1");
6141                }
6142                for (int i=0; i<mStartedUsers.size(); i++) {
6143                    UserStartedState uss = mStartedUsers.valueAt(i);
6144                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6145                        uss.mState = UserStartedState.STATE_RUNNING;
6146                        final int userId = mStartedUsers.keyAt(i);
6147                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6148                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6149                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6150                        broadcastIntentLocked(null, null, intent, null,
6151                                new IIntentReceiver.Stub() {
6152                                    @Override
6153                                    public void performReceive(Intent intent, int resultCode,
6154                                            String data, Bundle extras, boolean ordered,
6155                                            boolean sticky, int sendingUser) {
6156                                        synchronized (ActivityManagerService.this) {
6157                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6158                                                    true, false);
6159                                        }
6160                                    }
6161                                },
6162                                0, null, null,
6163                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6164                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6165                                userId);
6166                    }
6167                }
6168                scheduleStartProfilesLocked();
6169            }
6170        }
6171    }
6172
6173    @Override
6174    public void bootAnimationComplete() {
6175        final boolean callFinishBooting;
6176        synchronized (this) {
6177            callFinishBooting = mCallFinishBooting;
6178            mBootAnimationComplete = true;
6179        }
6180        if (callFinishBooting) {
6181            finishBooting();
6182        }
6183    }
6184
6185    final void ensureBootCompleted() {
6186        boolean booting;
6187        boolean enableScreen;
6188        synchronized (this) {
6189            booting = mBooting;
6190            mBooting = false;
6191            enableScreen = !mBooted;
6192            mBooted = true;
6193        }
6194
6195        if (booting) {
6196            finishBooting();
6197        }
6198
6199        if (enableScreen) {
6200            enableScreenAfterBoot();
6201        }
6202    }
6203
6204    @Override
6205    public final void activityResumed(IBinder token) {
6206        final long origId = Binder.clearCallingIdentity();
6207        synchronized(this) {
6208            ActivityStack stack = ActivityRecord.getStackLocked(token);
6209            if (stack != null) {
6210                ActivityRecord.activityResumedLocked(token);
6211            }
6212        }
6213        Binder.restoreCallingIdentity(origId);
6214    }
6215
6216    @Override
6217    public final void activityPaused(IBinder token) {
6218        final long origId = Binder.clearCallingIdentity();
6219        synchronized(this) {
6220            ActivityStack stack = ActivityRecord.getStackLocked(token);
6221            if (stack != null) {
6222                stack.activityPausedLocked(token, false);
6223            }
6224        }
6225        Binder.restoreCallingIdentity(origId);
6226    }
6227
6228    @Override
6229    public final void activityStopped(IBinder token, Bundle icicle,
6230            PersistableBundle persistentState, CharSequence description) {
6231        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6232
6233        // Refuse possible leaked file descriptors
6234        if (icicle != null && icicle.hasFileDescriptors()) {
6235            throw new IllegalArgumentException("File descriptors passed in Bundle");
6236        }
6237
6238        final long origId = Binder.clearCallingIdentity();
6239
6240        synchronized (this) {
6241            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6242            if (r != null) {
6243                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6244            }
6245        }
6246
6247        trimApplications();
6248
6249        Binder.restoreCallingIdentity(origId);
6250    }
6251
6252    @Override
6253    public final void activityDestroyed(IBinder token) {
6254        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6255        synchronized (this) {
6256            ActivityStack stack = ActivityRecord.getStackLocked(token);
6257            if (stack != null) {
6258                stack.activityDestroyedLocked(token);
6259            }
6260        }
6261    }
6262
6263    @Override
6264    public final void backgroundResourcesReleased(IBinder token) {
6265        final long origId = Binder.clearCallingIdentity();
6266        try {
6267            synchronized (this) {
6268                ActivityStack stack = ActivityRecord.getStackLocked(token);
6269                if (stack != null) {
6270                    stack.backgroundResourcesReleased();
6271                }
6272            }
6273        } finally {
6274            Binder.restoreCallingIdentity(origId);
6275        }
6276    }
6277
6278    @Override
6279    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6280        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6281    }
6282
6283    @Override
6284    public final void notifyEnterAnimationComplete(IBinder token) {
6285        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6286    }
6287
6288    @Override
6289    public String getCallingPackage(IBinder token) {
6290        synchronized (this) {
6291            ActivityRecord r = getCallingRecordLocked(token);
6292            return r != null ? r.info.packageName : null;
6293        }
6294    }
6295
6296    @Override
6297    public ComponentName getCallingActivity(IBinder token) {
6298        synchronized (this) {
6299            ActivityRecord r = getCallingRecordLocked(token);
6300            return r != null ? r.intent.getComponent() : null;
6301        }
6302    }
6303
6304    private ActivityRecord getCallingRecordLocked(IBinder token) {
6305        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6306        if (r == null) {
6307            return null;
6308        }
6309        return r.resultTo;
6310    }
6311
6312    @Override
6313    public ComponentName getActivityClassForToken(IBinder token) {
6314        synchronized(this) {
6315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6316            if (r == null) {
6317                return null;
6318            }
6319            return r.intent.getComponent();
6320        }
6321    }
6322
6323    @Override
6324    public String getPackageForToken(IBinder token) {
6325        synchronized(this) {
6326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6327            if (r == null) {
6328                return null;
6329            }
6330            return r.packageName;
6331        }
6332    }
6333
6334    @Override
6335    public IIntentSender getIntentSender(int type,
6336            String packageName, IBinder token, String resultWho,
6337            int requestCode, Intent[] intents, String[] resolvedTypes,
6338            int flags, Bundle options, int userId) {
6339        enforceNotIsolatedCaller("getIntentSender");
6340        // Refuse possible leaked file descriptors
6341        if (intents != null) {
6342            if (intents.length < 1) {
6343                throw new IllegalArgumentException("Intents array length must be >= 1");
6344            }
6345            for (int i=0; i<intents.length; i++) {
6346                Intent intent = intents[i];
6347                if (intent != null) {
6348                    if (intent.hasFileDescriptors()) {
6349                        throw new IllegalArgumentException("File descriptors passed in Intent");
6350                    }
6351                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6352                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6353                        throw new IllegalArgumentException(
6354                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6355                    }
6356                    intents[i] = new Intent(intent);
6357                }
6358            }
6359            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6360                throw new IllegalArgumentException(
6361                        "Intent array length does not match resolvedTypes length");
6362            }
6363        }
6364        if (options != null) {
6365            if (options.hasFileDescriptors()) {
6366                throw new IllegalArgumentException("File descriptors passed in options");
6367            }
6368        }
6369
6370        synchronized(this) {
6371            int callingUid = Binder.getCallingUid();
6372            int origUserId = userId;
6373            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6374                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6375                    ALLOW_NON_FULL, "getIntentSender", null);
6376            if (origUserId == UserHandle.USER_CURRENT) {
6377                // We don't want to evaluate this until the pending intent is
6378                // actually executed.  However, we do want to always do the
6379                // security checking for it above.
6380                userId = UserHandle.USER_CURRENT;
6381            }
6382            try {
6383                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6384                    int uid = AppGlobals.getPackageManager()
6385                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6386                    if (!UserHandle.isSameApp(callingUid, uid)) {
6387                        String msg = "Permission Denial: getIntentSender() from pid="
6388                            + Binder.getCallingPid()
6389                            + ", uid=" + Binder.getCallingUid()
6390                            + ", (need uid=" + uid + ")"
6391                            + " is not allowed to send as package " + packageName;
6392                        Slog.w(TAG, msg);
6393                        throw new SecurityException(msg);
6394                    }
6395                }
6396
6397                return getIntentSenderLocked(type, packageName, callingUid, userId,
6398                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6399
6400            } catch (RemoteException e) {
6401                throw new SecurityException(e);
6402            }
6403        }
6404    }
6405
6406    IIntentSender getIntentSenderLocked(int type, String packageName,
6407            int callingUid, int userId, IBinder token, String resultWho,
6408            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6409            Bundle options) {
6410        if (DEBUG_MU)
6411            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6412        ActivityRecord activity = null;
6413        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6414            activity = ActivityRecord.isInStackLocked(token);
6415            if (activity == null) {
6416                return null;
6417            }
6418            if (activity.finishing) {
6419                return null;
6420            }
6421        }
6422
6423        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6424        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6425        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6426        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6427                |PendingIntent.FLAG_UPDATE_CURRENT);
6428
6429        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6430                type, packageName, activity, resultWho,
6431                requestCode, intents, resolvedTypes, flags, options, userId);
6432        WeakReference<PendingIntentRecord> ref;
6433        ref = mIntentSenderRecords.get(key);
6434        PendingIntentRecord rec = ref != null ? ref.get() : null;
6435        if (rec != null) {
6436            if (!cancelCurrent) {
6437                if (updateCurrent) {
6438                    if (rec.key.requestIntent != null) {
6439                        rec.key.requestIntent.replaceExtras(intents != null ?
6440                                intents[intents.length - 1] : null);
6441                    }
6442                    if (intents != null) {
6443                        intents[intents.length-1] = rec.key.requestIntent;
6444                        rec.key.allIntents = intents;
6445                        rec.key.allResolvedTypes = resolvedTypes;
6446                    } else {
6447                        rec.key.allIntents = null;
6448                        rec.key.allResolvedTypes = null;
6449                    }
6450                }
6451                return rec;
6452            }
6453            rec.canceled = true;
6454            mIntentSenderRecords.remove(key);
6455        }
6456        if (noCreate) {
6457            return rec;
6458        }
6459        rec = new PendingIntentRecord(this, key, callingUid);
6460        mIntentSenderRecords.put(key, rec.ref);
6461        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6462            if (activity.pendingResults == null) {
6463                activity.pendingResults
6464                        = new HashSet<WeakReference<PendingIntentRecord>>();
6465            }
6466            activity.pendingResults.add(rec.ref);
6467        }
6468        return rec;
6469    }
6470
6471    @Override
6472    public void cancelIntentSender(IIntentSender sender) {
6473        if (!(sender instanceof PendingIntentRecord)) {
6474            return;
6475        }
6476        synchronized(this) {
6477            PendingIntentRecord rec = (PendingIntentRecord)sender;
6478            try {
6479                int uid = AppGlobals.getPackageManager()
6480                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6481                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6482                    String msg = "Permission Denial: cancelIntentSender() from pid="
6483                        + Binder.getCallingPid()
6484                        + ", uid=" + Binder.getCallingUid()
6485                        + " is not allowed to cancel packges "
6486                        + rec.key.packageName;
6487                    Slog.w(TAG, msg);
6488                    throw new SecurityException(msg);
6489                }
6490            } catch (RemoteException e) {
6491                throw new SecurityException(e);
6492            }
6493            cancelIntentSenderLocked(rec, true);
6494        }
6495    }
6496
6497    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6498        rec.canceled = true;
6499        mIntentSenderRecords.remove(rec.key);
6500        if (cleanActivity && rec.key.activity != null) {
6501            rec.key.activity.pendingResults.remove(rec.ref);
6502        }
6503    }
6504
6505    @Override
6506    public String getPackageForIntentSender(IIntentSender pendingResult) {
6507        if (!(pendingResult instanceof PendingIntentRecord)) {
6508            return null;
6509        }
6510        try {
6511            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6512            return res.key.packageName;
6513        } catch (ClassCastException e) {
6514        }
6515        return null;
6516    }
6517
6518    @Override
6519    public int getUidForIntentSender(IIntentSender sender) {
6520        if (sender instanceof PendingIntentRecord) {
6521            try {
6522                PendingIntentRecord res = (PendingIntentRecord)sender;
6523                return res.uid;
6524            } catch (ClassCastException e) {
6525            }
6526        }
6527        return -1;
6528    }
6529
6530    @Override
6531    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6532        if (!(pendingResult instanceof PendingIntentRecord)) {
6533            return false;
6534        }
6535        try {
6536            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6537            if (res.key.allIntents == null) {
6538                return false;
6539            }
6540            for (int i=0; i<res.key.allIntents.length; i++) {
6541                Intent intent = res.key.allIntents[i];
6542                if (intent.getPackage() != null && intent.getComponent() != null) {
6543                    return false;
6544                }
6545            }
6546            return true;
6547        } catch (ClassCastException e) {
6548        }
6549        return false;
6550    }
6551
6552    @Override
6553    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6554        if (!(pendingResult instanceof PendingIntentRecord)) {
6555            return false;
6556        }
6557        try {
6558            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6559            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6560                return true;
6561            }
6562            return false;
6563        } catch (ClassCastException e) {
6564        }
6565        return false;
6566    }
6567
6568    @Override
6569    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6570        if (!(pendingResult instanceof PendingIntentRecord)) {
6571            return null;
6572        }
6573        try {
6574            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6575            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6576        } catch (ClassCastException e) {
6577        }
6578        return null;
6579    }
6580
6581    @Override
6582    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6583        if (!(pendingResult instanceof PendingIntentRecord)) {
6584            return null;
6585        }
6586        try {
6587            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6588            Intent intent = res.key.requestIntent;
6589            if (intent != null) {
6590                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6591                        || res.lastTagPrefix.equals(prefix))) {
6592                    return res.lastTag;
6593                }
6594                res.lastTagPrefix = prefix;
6595                StringBuilder sb = new StringBuilder(128);
6596                if (prefix != null) {
6597                    sb.append(prefix);
6598                }
6599                if (intent.getAction() != null) {
6600                    sb.append(intent.getAction());
6601                } else if (intent.getComponent() != null) {
6602                    intent.getComponent().appendShortString(sb);
6603                } else {
6604                    sb.append("?");
6605                }
6606                return res.lastTag = sb.toString();
6607            }
6608        } catch (ClassCastException e) {
6609        }
6610        return null;
6611    }
6612
6613    @Override
6614    public void setProcessLimit(int max) {
6615        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6616                "setProcessLimit()");
6617        synchronized (this) {
6618            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6619            mProcessLimitOverride = max;
6620        }
6621        trimApplications();
6622    }
6623
6624    @Override
6625    public int getProcessLimit() {
6626        synchronized (this) {
6627            return mProcessLimitOverride;
6628        }
6629    }
6630
6631    void foregroundTokenDied(ForegroundToken token) {
6632        synchronized (ActivityManagerService.this) {
6633            synchronized (mPidsSelfLocked) {
6634                ForegroundToken cur
6635                    = mForegroundProcesses.get(token.pid);
6636                if (cur != token) {
6637                    return;
6638                }
6639                mForegroundProcesses.remove(token.pid);
6640                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6641                if (pr == null) {
6642                    return;
6643                }
6644                pr.forcingToForeground = null;
6645                updateProcessForegroundLocked(pr, false, false);
6646            }
6647            updateOomAdjLocked();
6648        }
6649    }
6650
6651    @Override
6652    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6653        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6654                "setProcessForeground()");
6655        synchronized(this) {
6656            boolean changed = false;
6657
6658            synchronized (mPidsSelfLocked) {
6659                ProcessRecord pr = mPidsSelfLocked.get(pid);
6660                if (pr == null && isForeground) {
6661                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6662                    return;
6663                }
6664                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6665                if (oldToken != null) {
6666                    oldToken.token.unlinkToDeath(oldToken, 0);
6667                    mForegroundProcesses.remove(pid);
6668                    if (pr != null) {
6669                        pr.forcingToForeground = null;
6670                    }
6671                    changed = true;
6672                }
6673                if (isForeground && token != null) {
6674                    ForegroundToken newToken = new ForegroundToken() {
6675                        @Override
6676                        public void binderDied() {
6677                            foregroundTokenDied(this);
6678                        }
6679                    };
6680                    newToken.pid = pid;
6681                    newToken.token = token;
6682                    try {
6683                        token.linkToDeath(newToken, 0);
6684                        mForegroundProcesses.put(pid, newToken);
6685                        pr.forcingToForeground = token;
6686                        changed = true;
6687                    } catch (RemoteException e) {
6688                        // If the process died while doing this, we will later
6689                        // do the cleanup with the process death link.
6690                    }
6691                }
6692            }
6693
6694            if (changed) {
6695                updateOomAdjLocked();
6696            }
6697        }
6698    }
6699
6700    // =========================================================
6701    // PERMISSIONS
6702    // =========================================================
6703
6704    static class PermissionController extends IPermissionController.Stub {
6705        ActivityManagerService mActivityManagerService;
6706        PermissionController(ActivityManagerService activityManagerService) {
6707            mActivityManagerService = activityManagerService;
6708        }
6709
6710        @Override
6711        public boolean checkPermission(String permission, int pid, int uid) {
6712            return mActivityManagerService.checkPermission(permission, pid,
6713                    uid) == PackageManager.PERMISSION_GRANTED;
6714        }
6715    }
6716
6717    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6718        @Override
6719        public int checkComponentPermission(String permission, int pid, int uid,
6720                int owningUid, boolean exported) {
6721            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6722                    owningUid, exported);
6723        }
6724
6725        @Override
6726        public Object getAMSLock() {
6727            return ActivityManagerService.this;
6728        }
6729    }
6730
6731    /**
6732     * This can be called with or without the global lock held.
6733     */
6734    int checkComponentPermission(String permission, int pid, int uid,
6735            int owningUid, boolean exported) {
6736        if (pid == MY_PID) {
6737            return PackageManager.PERMISSION_GRANTED;
6738        }
6739        return ActivityManager.checkComponentPermission(permission, uid,
6740                owningUid, exported);
6741    }
6742
6743    /**
6744     * As the only public entry point for permissions checking, this method
6745     * can enforce the semantic that requesting a check on a null global
6746     * permission is automatically denied.  (Internally a null permission
6747     * string is used when calling {@link #checkComponentPermission} in cases
6748     * when only uid-based security is needed.)
6749     *
6750     * This can be called with or without the global lock held.
6751     */
6752    @Override
6753    public int checkPermission(String permission, int pid, int uid) {
6754        if (permission == null) {
6755            return PackageManager.PERMISSION_DENIED;
6756        }
6757        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6758    }
6759
6760    @Override
6761    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6762        if (permission == null) {
6763            return PackageManager.PERMISSION_DENIED;
6764        }
6765
6766        // We might be performing an operation on behalf of an indirect binder
6767        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6768        // client identity accordingly before proceeding.
6769        Identity tlsIdentity = sCallerIdentity.get();
6770        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6771            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6772                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6773            uid = tlsIdentity.uid;
6774            pid = tlsIdentity.pid;
6775        }
6776
6777        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6778    }
6779
6780    /**
6781     * Binder IPC calls go through the public entry point.
6782     * This can be called with or without the global lock held.
6783     */
6784    int checkCallingPermission(String permission) {
6785        return checkPermission(permission,
6786                Binder.getCallingPid(),
6787                UserHandle.getAppId(Binder.getCallingUid()));
6788    }
6789
6790    /**
6791     * This can be called with or without the global lock held.
6792     */
6793    void enforceCallingPermission(String permission, String func) {
6794        if (checkCallingPermission(permission)
6795                == PackageManager.PERMISSION_GRANTED) {
6796            return;
6797        }
6798
6799        String msg = "Permission Denial: " + func + " from pid="
6800                + Binder.getCallingPid()
6801                + ", uid=" + Binder.getCallingUid()
6802                + " requires " + permission;
6803        Slog.w(TAG, msg);
6804        throw new SecurityException(msg);
6805    }
6806
6807    /**
6808     * Determine if UID is holding permissions required to access {@link Uri} in
6809     * the given {@link ProviderInfo}. Final permission checking is always done
6810     * in {@link ContentProvider}.
6811     */
6812    private final boolean checkHoldingPermissionsLocked(
6813            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6814        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6815                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6816        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6817            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6818                    != PERMISSION_GRANTED) {
6819                return false;
6820            }
6821        }
6822        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6823    }
6824
6825    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6826            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6827        if (pi.applicationInfo.uid == uid) {
6828            return true;
6829        } else if (!pi.exported) {
6830            return false;
6831        }
6832
6833        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6834        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6835        try {
6836            // check if target holds top-level <provider> permissions
6837            if (!readMet && pi.readPermission != null && considerUidPermissions
6838                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6839                readMet = true;
6840            }
6841            if (!writeMet && pi.writePermission != null && considerUidPermissions
6842                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6843                writeMet = true;
6844            }
6845
6846            // track if unprotected read/write is allowed; any denied
6847            // <path-permission> below removes this ability
6848            boolean allowDefaultRead = pi.readPermission == null;
6849            boolean allowDefaultWrite = pi.writePermission == null;
6850
6851            // check if target holds any <path-permission> that match uri
6852            final PathPermission[] pps = pi.pathPermissions;
6853            if (pps != null) {
6854                final String path = grantUri.uri.getPath();
6855                int i = pps.length;
6856                while (i > 0 && (!readMet || !writeMet)) {
6857                    i--;
6858                    PathPermission pp = pps[i];
6859                    if (pp.match(path)) {
6860                        if (!readMet) {
6861                            final String pprperm = pp.getReadPermission();
6862                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6863                                    + pprperm + " for " + pp.getPath()
6864                                    + ": match=" + pp.match(path)
6865                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6866                            if (pprperm != null) {
6867                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6868                                        == PERMISSION_GRANTED) {
6869                                    readMet = true;
6870                                } else {
6871                                    allowDefaultRead = false;
6872                                }
6873                            }
6874                        }
6875                        if (!writeMet) {
6876                            final String ppwperm = pp.getWritePermission();
6877                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6878                                    + ppwperm + " for " + pp.getPath()
6879                                    + ": match=" + pp.match(path)
6880                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6881                            if (ppwperm != null) {
6882                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6883                                        == PERMISSION_GRANTED) {
6884                                    writeMet = true;
6885                                } else {
6886                                    allowDefaultWrite = false;
6887                                }
6888                            }
6889                        }
6890                    }
6891                }
6892            }
6893
6894            // grant unprotected <provider> read/write, if not blocked by
6895            // <path-permission> above
6896            if (allowDefaultRead) readMet = true;
6897            if (allowDefaultWrite) writeMet = true;
6898
6899        } catch (RemoteException e) {
6900            return false;
6901        }
6902
6903        return readMet && writeMet;
6904    }
6905
6906    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6907        ProviderInfo pi = null;
6908        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6909        if (cpr != null) {
6910            pi = cpr.info;
6911        } else {
6912            try {
6913                pi = AppGlobals.getPackageManager().resolveContentProvider(
6914                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6915            } catch (RemoteException ex) {
6916            }
6917        }
6918        return pi;
6919    }
6920
6921    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6922        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6923        if (targetUris != null) {
6924            return targetUris.get(grantUri);
6925        }
6926        return null;
6927    }
6928
6929    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6930            String targetPkg, int targetUid, GrantUri grantUri) {
6931        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6932        if (targetUris == null) {
6933            targetUris = Maps.newArrayMap();
6934            mGrantedUriPermissions.put(targetUid, targetUris);
6935        }
6936
6937        UriPermission perm = targetUris.get(grantUri);
6938        if (perm == null) {
6939            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6940            targetUris.put(grantUri, perm);
6941        }
6942
6943        return perm;
6944    }
6945
6946    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6947            final int modeFlags) {
6948        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6949        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6950                : UriPermission.STRENGTH_OWNED;
6951
6952        // Root gets to do everything.
6953        if (uid == 0) {
6954            return true;
6955        }
6956
6957        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6958        if (perms == null) return false;
6959
6960        // First look for exact match
6961        final UriPermission exactPerm = perms.get(grantUri);
6962        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6963            return true;
6964        }
6965
6966        // No exact match, look for prefixes
6967        final int N = perms.size();
6968        for (int i = 0; i < N; i++) {
6969            final UriPermission perm = perms.valueAt(i);
6970            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6971                    && perm.getStrength(modeFlags) >= minStrength) {
6972                return true;
6973            }
6974        }
6975
6976        return false;
6977    }
6978
6979    /**
6980     * @param uri This uri must NOT contain an embedded userId.
6981     * @param userId The userId in which the uri is to be resolved.
6982     */
6983    @Override
6984    public int checkUriPermission(Uri uri, int pid, int uid,
6985            final int modeFlags, int userId, IBinder callerToken) {
6986        enforceNotIsolatedCaller("checkUriPermission");
6987
6988        // Another redirected-binder-call permissions check as in
6989        // {@link checkPermissionWithToken}.
6990        Identity tlsIdentity = sCallerIdentity.get();
6991        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6992            uid = tlsIdentity.uid;
6993            pid = tlsIdentity.pid;
6994        }
6995
6996        // Our own process gets to do everything.
6997        if (pid == MY_PID) {
6998            return PackageManager.PERMISSION_GRANTED;
6999        }
7000        synchronized (this) {
7001            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7002                    ? PackageManager.PERMISSION_GRANTED
7003                    : PackageManager.PERMISSION_DENIED;
7004        }
7005    }
7006
7007    /**
7008     * Check if the targetPkg can be granted permission to access uri by
7009     * the callingUid using the given modeFlags.  Throws a security exception
7010     * if callingUid is not allowed to do this.  Returns the uid of the target
7011     * if the URI permission grant should be performed; returns -1 if it is not
7012     * needed (for example targetPkg already has permission to access the URI).
7013     * If you already know the uid of the target, you can supply it in
7014     * lastTargetUid else set that to -1.
7015     */
7016    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7017            final int modeFlags, int lastTargetUid) {
7018        if (!Intent.isAccessUriMode(modeFlags)) {
7019            return -1;
7020        }
7021
7022        if (targetPkg != null) {
7023            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7024                    "Checking grant " + targetPkg + " permission to " + grantUri);
7025        }
7026
7027        final IPackageManager pm = AppGlobals.getPackageManager();
7028
7029        // If this is not a content: uri, we can't do anything with it.
7030        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7031            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7032                    "Can't grant URI permission for non-content URI: " + grantUri);
7033            return -1;
7034        }
7035
7036        final String authority = grantUri.uri.getAuthority();
7037        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7038        if (pi == null) {
7039            Slog.w(TAG, "No content provider found for permission check: " +
7040                    grantUri.uri.toSafeString());
7041            return -1;
7042        }
7043
7044        int targetUid = lastTargetUid;
7045        if (targetUid < 0 && targetPkg != null) {
7046            try {
7047                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7048                if (targetUid < 0) {
7049                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7050                            "Can't grant URI permission no uid for: " + targetPkg);
7051                    return -1;
7052                }
7053            } catch (RemoteException ex) {
7054                return -1;
7055            }
7056        }
7057
7058        if (targetUid >= 0) {
7059            // First...  does the target actually need this permission?
7060            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7061                // No need to grant the target this permission.
7062                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7063                        "Target " + targetPkg + " already has full permission to " + grantUri);
7064                return -1;
7065            }
7066        } else {
7067            // First...  there is no target package, so can anyone access it?
7068            boolean allowed = pi.exported;
7069            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7070                if (pi.readPermission != null) {
7071                    allowed = false;
7072                }
7073            }
7074            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7075                if (pi.writePermission != null) {
7076                    allowed = false;
7077                }
7078            }
7079            if (allowed) {
7080                return -1;
7081            }
7082        }
7083
7084        /* There is a special cross user grant if:
7085         * - The target is on another user.
7086         * - Apps on the current user can access the uri without any uid permissions.
7087         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7088         * grant uri permissions.
7089         */
7090        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7091                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7092                modeFlags, false /*without considering the uid permissions*/);
7093
7094        // Second...  is the provider allowing granting of URI permissions?
7095        if (!specialCrossUserGrant) {
7096            if (!pi.grantUriPermissions) {
7097                throw new SecurityException("Provider " + pi.packageName
7098                        + "/" + pi.name
7099                        + " does not allow granting of Uri permissions (uri "
7100                        + grantUri + ")");
7101            }
7102            if (pi.uriPermissionPatterns != null) {
7103                final int N = pi.uriPermissionPatterns.length;
7104                boolean allowed = false;
7105                for (int i=0; i<N; i++) {
7106                    if (pi.uriPermissionPatterns[i] != null
7107                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7108                        allowed = true;
7109                        break;
7110                    }
7111                }
7112                if (!allowed) {
7113                    throw new SecurityException("Provider " + pi.packageName
7114                            + "/" + pi.name
7115                            + " does not allow granting of permission to path of Uri "
7116                            + grantUri);
7117                }
7118            }
7119        }
7120
7121        // Third...  does the caller itself have permission to access
7122        // this uri?
7123        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7124            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7125                // Require they hold a strong enough Uri permission
7126                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7127                    throw new SecurityException("Uid " + callingUid
7128                            + " does not have permission to uri " + grantUri);
7129                }
7130            }
7131        }
7132        return targetUid;
7133    }
7134
7135    /**
7136     * @param uri This uri must NOT contain an embedded userId.
7137     * @param userId The userId in which the uri is to be resolved.
7138     */
7139    @Override
7140    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7141            final int modeFlags, int userId) {
7142        enforceNotIsolatedCaller("checkGrantUriPermission");
7143        synchronized(this) {
7144            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7145                    new GrantUri(userId, uri, false), modeFlags, -1);
7146        }
7147    }
7148
7149    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7150            final int modeFlags, UriPermissionOwner owner) {
7151        if (!Intent.isAccessUriMode(modeFlags)) {
7152            return;
7153        }
7154
7155        // So here we are: the caller has the assumed permission
7156        // to the uri, and the target doesn't.  Let's now give this to
7157        // the target.
7158
7159        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7160                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7161
7162        final String authority = grantUri.uri.getAuthority();
7163        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7164        if (pi == null) {
7165            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7166            return;
7167        }
7168
7169        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7170            grantUri.prefix = true;
7171        }
7172        final UriPermission perm = findOrCreateUriPermissionLocked(
7173                pi.packageName, targetPkg, targetUid, grantUri);
7174        perm.grantModes(modeFlags, owner);
7175    }
7176
7177    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7178            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7179        if (targetPkg == null) {
7180            throw new NullPointerException("targetPkg");
7181        }
7182        int targetUid;
7183        final IPackageManager pm = AppGlobals.getPackageManager();
7184        try {
7185            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7186        } catch (RemoteException ex) {
7187            return;
7188        }
7189
7190        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7191                targetUid);
7192        if (targetUid < 0) {
7193            return;
7194        }
7195
7196        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7197                owner);
7198    }
7199
7200    static class NeededUriGrants extends ArrayList<GrantUri> {
7201        final String targetPkg;
7202        final int targetUid;
7203        final int flags;
7204
7205        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7206            this.targetPkg = targetPkg;
7207            this.targetUid = targetUid;
7208            this.flags = flags;
7209        }
7210    }
7211
7212    /**
7213     * Like checkGrantUriPermissionLocked, but takes an Intent.
7214     */
7215    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7216            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7217        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7218                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7219                + " clip=" + (intent != null ? intent.getClipData() : null)
7220                + " from " + intent + "; flags=0x"
7221                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7222
7223        if (targetPkg == null) {
7224            throw new NullPointerException("targetPkg");
7225        }
7226
7227        if (intent == null) {
7228            return null;
7229        }
7230        Uri data = intent.getData();
7231        ClipData clip = intent.getClipData();
7232        if (data == null && clip == null) {
7233            return null;
7234        }
7235        // Default userId for uris in the intent (if they don't specify it themselves)
7236        int contentUserHint = intent.getContentUserHint();
7237        if (contentUserHint == UserHandle.USER_CURRENT) {
7238            contentUserHint = UserHandle.getUserId(callingUid);
7239        }
7240        final IPackageManager pm = AppGlobals.getPackageManager();
7241        int targetUid;
7242        if (needed != null) {
7243            targetUid = needed.targetUid;
7244        } else {
7245            try {
7246                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7247            } catch (RemoteException ex) {
7248                return null;
7249            }
7250            if (targetUid < 0) {
7251                if (DEBUG_URI_PERMISSION) {
7252                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7253                            + " on user " + targetUserId);
7254                }
7255                return null;
7256            }
7257        }
7258        if (data != null) {
7259            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7260            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7261                    targetUid);
7262            if (targetUid > 0) {
7263                if (needed == null) {
7264                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7265                }
7266                needed.add(grantUri);
7267            }
7268        }
7269        if (clip != null) {
7270            for (int i=0; i<clip.getItemCount(); i++) {
7271                Uri uri = clip.getItemAt(i).getUri();
7272                if (uri != null) {
7273                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7274                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7275                            targetUid);
7276                    if (targetUid > 0) {
7277                        if (needed == null) {
7278                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7279                        }
7280                        needed.add(grantUri);
7281                    }
7282                } else {
7283                    Intent clipIntent = clip.getItemAt(i).getIntent();
7284                    if (clipIntent != null) {
7285                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7286                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7287                        if (newNeeded != null) {
7288                            needed = newNeeded;
7289                        }
7290                    }
7291                }
7292            }
7293        }
7294
7295        return needed;
7296    }
7297
7298    /**
7299     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7300     */
7301    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7302            UriPermissionOwner owner) {
7303        if (needed != null) {
7304            for (int i=0; i<needed.size(); i++) {
7305                GrantUri grantUri = needed.get(i);
7306                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7307                        grantUri, needed.flags, owner);
7308            }
7309        }
7310    }
7311
7312    void grantUriPermissionFromIntentLocked(int callingUid,
7313            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7314        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7315                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7316        if (needed == null) {
7317            return;
7318        }
7319
7320        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7321    }
7322
7323    /**
7324     * @param uri This uri must NOT contain an embedded userId.
7325     * @param userId The userId in which the uri is to be resolved.
7326     */
7327    @Override
7328    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7329            final int modeFlags, int userId) {
7330        enforceNotIsolatedCaller("grantUriPermission");
7331        GrantUri grantUri = new GrantUri(userId, uri, false);
7332        synchronized(this) {
7333            final ProcessRecord r = getRecordForAppLocked(caller);
7334            if (r == null) {
7335                throw new SecurityException("Unable to find app for caller "
7336                        + caller
7337                        + " when granting permission to uri " + grantUri);
7338            }
7339            if (targetPkg == null) {
7340                throw new IllegalArgumentException("null target");
7341            }
7342            if (grantUri == null) {
7343                throw new IllegalArgumentException("null uri");
7344            }
7345
7346            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7347                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7348                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7349                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7350
7351            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7352                    UserHandle.getUserId(r.uid));
7353        }
7354    }
7355
7356    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7357        if (perm.modeFlags == 0) {
7358            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7359                    perm.targetUid);
7360            if (perms != null) {
7361                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7362                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7363
7364                perms.remove(perm.uri);
7365                if (perms.isEmpty()) {
7366                    mGrantedUriPermissions.remove(perm.targetUid);
7367                }
7368            }
7369        }
7370    }
7371
7372    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7373        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7374
7375        final IPackageManager pm = AppGlobals.getPackageManager();
7376        final String authority = grantUri.uri.getAuthority();
7377        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7378        if (pi == null) {
7379            Slog.w(TAG, "No content provider found for permission revoke: "
7380                    + grantUri.toSafeString());
7381            return;
7382        }
7383
7384        // Does the caller have this permission on the URI?
7385        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7386            // If they don't have direct access to the URI, then revoke any
7387            // ownerless URI permissions that have been granted to them.
7388            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7389            if (perms != null) {
7390                boolean persistChanged = false;
7391                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7392                    final UriPermission perm = it.next();
7393                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7394                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7395                        if (DEBUG_URI_PERMISSION)
7396                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7397                                    " permission to " + perm.uri);
7398                        persistChanged |= perm.revokeModes(
7399                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7400                        if (perm.modeFlags == 0) {
7401                            it.remove();
7402                        }
7403                    }
7404                }
7405                if (perms.isEmpty()) {
7406                    mGrantedUriPermissions.remove(callingUid);
7407                }
7408                if (persistChanged) {
7409                    schedulePersistUriGrants();
7410                }
7411            }
7412            return;
7413        }
7414
7415        boolean persistChanged = false;
7416
7417        // Go through all of the permissions and remove any that match.
7418        int N = mGrantedUriPermissions.size();
7419        for (int i = 0; i < N; i++) {
7420            final int targetUid = mGrantedUriPermissions.keyAt(i);
7421            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7422
7423            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7424                final UriPermission perm = it.next();
7425                if (perm.uri.sourceUserId == grantUri.sourceUserId
7426                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7427                    if (DEBUG_URI_PERMISSION)
7428                        Slog.v(TAG,
7429                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7430                    persistChanged |= perm.revokeModes(
7431                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7432                    if (perm.modeFlags == 0) {
7433                        it.remove();
7434                    }
7435                }
7436            }
7437
7438            if (perms.isEmpty()) {
7439                mGrantedUriPermissions.remove(targetUid);
7440                N--;
7441                i--;
7442            }
7443        }
7444
7445        if (persistChanged) {
7446            schedulePersistUriGrants();
7447        }
7448    }
7449
7450    /**
7451     * @param uri This uri must NOT contain an embedded userId.
7452     * @param userId The userId in which the uri is to be resolved.
7453     */
7454    @Override
7455    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7456            int userId) {
7457        enforceNotIsolatedCaller("revokeUriPermission");
7458        synchronized(this) {
7459            final ProcessRecord r = getRecordForAppLocked(caller);
7460            if (r == null) {
7461                throw new SecurityException("Unable to find app for caller "
7462                        + caller
7463                        + " when revoking permission to uri " + uri);
7464            }
7465            if (uri == null) {
7466                Slog.w(TAG, "revokeUriPermission: null uri");
7467                return;
7468            }
7469
7470            if (!Intent.isAccessUriMode(modeFlags)) {
7471                return;
7472            }
7473
7474            final IPackageManager pm = AppGlobals.getPackageManager();
7475            final String authority = uri.getAuthority();
7476            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7477            if (pi == null) {
7478                Slog.w(TAG, "No content provider found for permission revoke: "
7479                        + uri.toSafeString());
7480                return;
7481            }
7482
7483            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7484        }
7485    }
7486
7487    /**
7488     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7489     * given package.
7490     *
7491     * @param packageName Package name to match, or {@code null} to apply to all
7492     *            packages.
7493     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7494     *            to all users.
7495     * @param persistable If persistable grants should be removed.
7496     */
7497    private void removeUriPermissionsForPackageLocked(
7498            String packageName, int userHandle, boolean persistable) {
7499        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7500            throw new IllegalArgumentException("Must narrow by either package or user");
7501        }
7502
7503        boolean persistChanged = false;
7504
7505        int N = mGrantedUriPermissions.size();
7506        for (int i = 0; i < N; i++) {
7507            final int targetUid = mGrantedUriPermissions.keyAt(i);
7508            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7509
7510            // Only inspect grants matching user
7511            if (userHandle == UserHandle.USER_ALL
7512                    || userHandle == UserHandle.getUserId(targetUid)) {
7513                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7514                    final UriPermission perm = it.next();
7515
7516                    // Only inspect grants matching package
7517                    if (packageName == null || perm.sourcePkg.equals(packageName)
7518                            || perm.targetPkg.equals(packageName)) {
7519                        persistChanged |= perm.revokeModes(persistable
7520                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7521
7522                        // Only remove when no modes remain; any persisted grants
7523                        // will keep this alive.
7524                        if (perm.modeFlags == 0) {
7525                            it.remove();
7526                        }
7527                    }
7528                }
7529
7530                if (perms.isEmpty()) {
7531                    mGrantedUriPermissions.remove(targetUid);
7532                    N--;
7533                    i--;
7534                }
7535            }
7536        }
7537
7538        if (persistChanged) {
7539            schedulePersistUriGrants();
7540        }
7541    }
7542
7543    @Override
7544    public IBinder newUriPermissionOwner(String name) {
7545        enforceNotIsolatedCaller("newUriPermissionOwner");
7546        synchronized(this) {
7547            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7548            return owner.getExternalTokenLocked();
7549        }
7550    }
7551
7552    /**
7553     * @param uri This uri must NOT contain an embedded userId.
7554     * @param sourceUserId The userId in which the uri is to be resolved.
7555     * @param targetUserId The userId of the app that receives the grant.
7556     */
7557    @Override
7558    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7559            final int modeFlags, int sourceUserId, int targetUserId) {
7560        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7561                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7562        synchronized(this) {
7563            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7564            if (owner == null) {
7565                throw new IllegalArgumentException("Unknown owner: " + token);
7566            }
7567            if (fromUid != Binder.getCallingUid()) {
7568                if (Binder.getCallingUid() != Process.myUid()) {
7569                    // Only system code can grant URI permissions on behalf
7570                    // of other users.
7571                    throw new SecurityException("nice try");
7572                }
7573            }
7574            if (targetPkg == null) {
7575                throw new IllegalArgumentException("null target");
7576            }
7577            if (uri == null) {
7578                throw new IllegalArgumentException("null uri");
7579            }
7580
7581            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7582                    modeFlags, owner, targetUserId);
7583        }
7584    }
7585
7586    /**
7587     * @param uri This uri must NOT contain an embedded userId.
7588     * @param userId The userId in which the uri is to be resolved.
7589     */
7590    @Override
7591    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7592        synchronized(this) {
7593            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7594            if (owner == null) {
7595                throw new IllegalArgumentException("Unknown owner: " + token);
7596            }
7597
7598            if (uri == null) {
7599                owner.removeUriPermissionsLocked(mode);
7600            } else {
7601                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7602            }
7603        }
7604    }
7605
7606    private void schedulePersistUriGrants() {
7607        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7608            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7609                    10 * DateUtils.SECOND_IN_MILLIS);
7610        }
7611    }
7612
7613    private void writeGrantedUriPermissions() {
7614        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7615
7616        // Snapshot permissions so we can persist without lock
7617        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7618        synchronized (this) {
7619            final int size = mGrantedUriPermissions.size();
7620            for (int i = 0; i < size; i++) {
7621                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7622                for (UriPermission perm : perms.values()) {
7623                    if (perm.persistedModeFlags != 0) {
7624                        persist.add(perm.snapshot());
7625                    }
7626                }
7627            }
7628        }
7629
7630        FileOutputStream fos = null;
7631        try {
7632            fos = mGrantFile.startWrite();
7633
7634            XmlSerializer out = new FastXmlSerializer();
7635            out.setOutput(fos, "utf-8");
7636            out.startDocument(null, true);
7637            out.startTag(null, TAG_URI_GRANTS);
7638            for (UriPermission.Snapshot perm : persist) {
7639                out.startTag(null, TAG_URI_GRANT);
7640                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7641                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7642                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7643                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7644                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7645                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7646                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7647                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7648                out.endTag(null, TAG_URI_GRANT);
7649            }
7650            out.endTag(null, TAG_URI_GRANTS);
7651            out.endDocument();
7652
7653            mGrantFile.finishWrite(fos);
7654        } catch (IOException e) {
7655            if (fos != null) {
7656                mGrantFile.failWrite(fos);
7657            }
7658        }
7659    }
7660
7661    private void readGrantedUriPermissionsLocked() {
7662        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7663
7664        final long now = System.currentTimeMillis();
7665
7666        FileInputStream fis = null;
7667        try {
7668            fis = mGrantFile.openRead();
7669            final XmlPullParser in = Xml.newPullParser();
7670            in.setInput(fis, null);
7671
7672            int type;
7673            while ((type = in.next()) != END_DOCUMENT) {
7674                final String tag = in.getName();
7675                if (type == START_TAG) {
7676                    if (TAG_URI_GRANT.equals(tag)) {
7677                        final int sourceUserId;
7678                        final int targetUserId;
7679                        final int userHandle = readIntAttribute(in,
7680                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7681                        if (userHandle != UserHandle.USER_NULL) {
7682                            // For backwards compatibility.
7683                            sourceUserId = userHandle;
7684                            targetUserId = userHandle;
7685                        } else {
7686                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7687                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7688                        }
7689                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7690                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7691                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7692                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7693                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7694                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7695
7696                        // Sanity check that provider still belongs to source package
7697                        final ProviderInfo pi = getProviderInfoLocked(
7698                                uri.getAuthority(), sourceUserId);
7699                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7700                            int targetUid = -1;
7701                            try {
7702                                targetUid = AppGlobals.getPackageManager()
7703                                        .getPackageUid(targetPkg, targetUserId);
7704                            } catch (RemoteException e) {
7705                            }
7706                            if (targetUid != -1) {
7707                                final UriPermission perm = findOrCreateUriPermissionLocked(
7708                                        sourcePkg, targetPkg, targetUid,
7709                                        new GrantUri(sourceUserId, uri, prefix));
7710                                perm.initPersistedModes(modeFlags, createdTime);
7711                            }
7712                        } else {
7713                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7714                                    + " but instead found " + pi);
7715                        }
7716                    }
7717                }
7718            }
7719        } catch (FileNotFoundException e) {
7720            // Missing grants is okay
7721        } catch (IOException e) {
7722            Slog.wtf(TAG, "Failed reading Uri grants", e);
7723        } catch (XmlPullParserException e) {
7724            Slog.wtf(TAG, "Failed reading Uri grants", e);
7725        } finally {
7726            IoUtils.closeQuietly(fis);
7727        }
7728    }
7729
7730    /**
7731     * @param uri This uri must NOT contain an embedded userId.
7732     * @param userId The userId in which the uri is to be resolved.
7733     */
7734    @Override
7735    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7736        enforceNotIsolatedCaller("takePersistableUriPermission");
7737
7738        Preconditions.checkFlagsArgument(modeFlags,
7739                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7740
7741        synchronized (this) {
7742            final int callingUid = Binder.getCallingUid();
7743            boolean persistChanged = false;
7744            GrantUri grantUri = new GrantUri(userId, uri, false);
7745
7746            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7747                    new GrantUri(userId, uri, false));
7748            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7749                    new GrantUri(userId, uri, true));
7750
7751            final boolean exactValid = (exactPerm != null)
7752                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7753            final boolean prefixValid = (prefixPerm != null)
7754                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7755
7756            if (!(exactValid || prefixValid)) {
7757                throw new SecurityException("No persistable permission grants found for UID "
7758                        + callingUid + " and Uri " + grantUri.toSafeString());
7759            }
7760
7761            if (exactValid) {
7762                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7763            }
7764            if (prefixValid) {
7765                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7766            }
7767
7768            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7769
7770            if (persistChanged) {
7771                schedulePersistUriGrants();
7772            }
7773        }
7774    }
7775
7776    /**
7777     * @param uri This uri must NOT contain an embedded userId.
7778     * @param userId The userId in which the uri is to be resolved.
7779     */
7780    @Override
7781    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7782        enforceNotIsolatedCaller("releasePersistableUriPermission");
7783
7784        Preconditions.checkFlagsArgument(modeFlags,
7785                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7786
7787        synchronized (this) {
7788            final int callingUid = Binder.getCallingUid();
7789            boolean persistChanged = false;
7790
7791            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7792                    new GrantUri(userId, uri, false));
7793            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7794                    new GrantUri(userId, uri, true));
7795            if (exactPerm == null && prefixPerm == null) {
7796                throw new SecurityException("No permission grants found for UID " + callingUid
7797                        + " and Uri " + uri.toSafeString());
7798            }
7799
7800            if (exactPerm != null) {
7801                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7802                removeUriPermissionIfNeededLocked(exactPerm);
7803            }
7804            if (prefixPerm != null) {
7805                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7806                removeUriPermissionIfNeededLocked(prefixPerm);
7807            }
7808
7809            if (persistChanged) {
7810                schedulePersistUriGrants();
7811            }
7812        }
7813    }
7814
7815    /**
7816     * Prune any older {@link UriPermission} for the given UID until outstanding
7817     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7818     *
7819     * @return if any mutations occured that require persisting.
7820     */
7821    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7822        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7823        if (perms == null) return false;
7824        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7825
7826        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7827        for (UriPermission perm : perms.values()) {
7828            if (perm.persistedModeFlags != 0) {
7829                persisted.add(perm);
7830            }
7831        }
7832
7833        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7834        if (trimCount <= 0) return false;
7835
7836        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7837        for (int i = 0; i < trimCount; i++) {
7838            final UriPermission perm = persisted.get(i);
7839
7840            if (DEBUG_URI_PERMISSION) {
7841                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7842            }
7843
7844            perm.releasePersistableModes(~0);
7845            removeUriPermissionIfNeededLocked(perm);
7846        }
7847
7848        return true;
7849    }
7850
7851    @Override
7852    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7853            String packageName, boolean incoming) {
7854        enforceNotIsolatedCaller("getPersistedUriPermissions");
7855        Preconditions.checkNotNull(packageName, "packageName");
7856
7857        final int callingUid = Binder.getCallingUid();
7858        final IPackageManager pm = AppGlobals.getPackageManager();
7859        try {
7860            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7861            if (packageUid != callingUid) {
7862                throw new SecurityException(
7863                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7864            }
7865        } catch (RemoteException e) {
7866            throw new SecurityException("Failed to verify package name ownership");
7867        }
7868
7869        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7870        synchronized (this) {
7871            if (incoming) {
7872                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7873                        callingUid);
7874                if (perms == null) {
7875                    Slog.w(TAG, "No permission grants found for " + packageName);
7876                } else {
7877                    for (UriPermission perm : perms.values()) {
7878                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7879                            result.add(perm.buildPersistedPublicApiObject());
7880                        }
7881                    }
7882                }
7883            } else {
7884                final int size = mGrantedUriPermissions.size();
7885                for (int i = 0; i < size; i++) {
7886                    final ArrayMap<GrantUri, UriPermission> perms =
7887                            mGrantedUriPermissions.valueAt(i);
7888                    for (UriPermission perm : perms.values()) {
7889                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7890                            result.add(perm.buildPersistedPublicApiObject());
7891                        }
7892                    }
7893                }
7894            }
7895        }
7896        return new ParceledListSlice<android.content.UriPermission>(result);
7897    }
7898
7899    @Override
7900    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7901        synchronized (this) {
7902            ProcessRecord app =
7903                who != null ? getRecordForAppLocked(who) : null;
7904            if (app == null) return;
7905
7906            Message msg = Message.obtain();
7907            msg.what = WAIT_FOR_DEBUGGER_MSG;
7908            msg.obj = app;
7909            msg.arg1 = waiting ? 1 : 0;
7910            mHandler.sendMessage(msg);
7911        }
7912    }
7913
7914    @Override
7915    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7916        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7917        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7918        outInfo.availMem = Process.getFreeMemory();
7919        outInfo.totalMem = Process.getTotalMemory();
7920        outInfo.threshold = homeAppMem;
7921        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7922        outInfo.hiddenAppThreshold = cachedAppMem;
7923        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7924                ProcessList.SERVICE_ADJ);
7925        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7926                ProcessList.VISIBLE_APP_ADJ);
7927        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7928                ProcessList.FOREGROUND_APP_ADJ);
7929    }
7930
7931    // =========================================================
7932    // TASK MANAGEMENT
7933    // =========================================================
7934
7935    @Override
7936    public List<IAppTask> getAppTasks(String callingPackage) {
7937        int callingUid = Binder.getCallingUid();
7938        long ident = Binder.clearCallingIdentity();
7939
7940        synchronized(this) {
7941            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7942            try {
7943                if (localLOGV) Slog.v(TAG, "getAppTasks");
7944
7945                final int N = mRecentTasks.size();
7946                for (int i = 0; i < N; i++) {
7947                    TaskRecord tr = mRecentTasks.get(i);
7948                    // Skip tasks that do not match the caller.  We don't need to verify
7949                    // callingPackage, because we are also limiting to callingUid and know
7950                    // that will limit to the correct security sandbox.
7951                    if (tr.effectiveUid != callingUid) {
7952                        continue;
7953                    }
7954                    Intent intent = tr.getBaseIntent();
7955                    if (intent == null ||
7956                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7957                        continue;
7958                    }
7959                    ActivityManager.RecentTaskInfo taskInfo =
7960                            createRecentTaskInfoFromTaskRecord(tr);
7961                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7962                    list.add(taskImpl);
7963                }
7964            } finally {
7965                Binder.restoreCallingIdentity(ident);
7966            }
7967            return list;
7968        }
7969    }
7970
7971    @Override
7972    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7973        final int callingUid = Binder.getCallingUid();
7974        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7975
7976        synchronized(this) {
7977            if (localLOGV) Slog.v(
7978                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7979
7980            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7981                    callingUid);
7982
7983            // TODO: Improve with MRU list from all ActivityStacks.
7984            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7985        }
7986
7987        return list;
7988    }
7989
7990    TaskRecord getMostRecentTask() {
7991        return mRecentTasks.get(0);
7992    }
7993
7994    /**
7995     * Creates a new RecentTaskInfo from a TaskRecord.
7996     */
7997    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7998        // Update the task description to reflect any changes in the task stack
7999        tr.updateTaskDescription();
8000
8001        // Compose the recent task info
8002        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8003        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8004        rti.persistentId = tr.taskId;
8005        rti.baseIntent = new Intent(tr.getBaseIntent());
8006        rti.origActivity = tr.origActivity;
8007        rti.description = tr.lastDescription;
8008        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8009        rti.userId = tr.userId;
8010        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8011        rti.firstActiveTime = tr.firstActiveTime;
8012        rti.lastActiveTime = tr.lastActiveTime;
8013        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8014        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8015        return rti;
8016    }
8017
8018    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8019        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8020                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8021        if (!allowed) {
8022            if (checkPermission(android.Manifest.permission.GET_TASKS,
8023                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8024                // Temporary compatibility: some existing apps on the system image may
8025                // still be requesting the old permission and not switched to the new
8026                // one; if so, we'll still allow them full access.  This means we need
8027                // to see if they are holding the old permission and are a system app.
8028                try {
8029                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8030                        allowed = true;
8031                        Slog.w(TAG, caller + ": caller " + callingUid
8032                                + " is using old GET_TASKS but privileged; allowing");
8033                    }
8034                } catch (RemoteException e) {
8035                }
8036            }
8037        }
8038        if (!allowed) {
8039            Slog.w(TAG, caller + ": caller " + callingUid
8040                    + " does not hold GET_TASKS; limiting output");
8041        }
8042        return allowed;
8043    }
8044
8045    @Override
8046    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8047        final int callingUid = Binder.getCallingUid();
8048        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8049                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8050
8051        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8052        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8053        synchronized (this) {
8054            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8055                    callingUid);
8056            final boolean detailed = checkCallingPermission(
8057                    android.Manifest.permission.GET_DETAILED_TASKS)
8058                    == PackageManager.PERMISSION_GRANTED;
8059
8060            final int N = mRecentTasks.size();
8061            ArrayList<ActivityManager.RecentTaskInfo> res
8062                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8063                            maxNum < N ? maxNum : N);
8064
8065            final Set<Integer> includedUsers;
8066            if (includeProfiles) {
8067                includedUsers = getProfileIdsLocked(userId);
8068            } else {
8069                includedUsers = new HashSet<Integer>();
8070            }
8071            includedUsers.add(Integer.valueOf(userId));
8072
8073            for (int i=0; i<N && maxNum > 0; i++) {
8074                TaskRecord tr = mRecentTasks.get(i);
8075                // Only add calling user or related users recent tasks
8076                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8077                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8078                    continue;
8079                }
8080
8081                // Return the entry if desired by the caller.  We always return
8082                // the first entry, because callers always expect this to be the
8083                // foreground app.  We may filter others if the caller has
8084                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8085                // we should exclude the entry.
8086
8087                if (i == 0
8088                        || withExcluded
8089                        || (tr.intent == null)
8090                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8091                                == 0)) {
8092                    if (!allowed) {
8093                        // If the caller doesn't have the GET_TASKS permission, then only
8094                        // allow them to see a small subset of tasks -- their own and home.
8095                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8096                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8097                            continue;
8098                        }
8099                    }
8100                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8101                        if (tr.stack != null && tr.stack.isHomeStack()) {
8102                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8103                            continue;
8104                        }
8105                    }
8106                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8107                        // Don't include auto remove tasks that are finished or finishing.
8108                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8109                                + tr);
8110                        continue;
8111                    }
8112                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8113                            && !tr.isAvailable) {
8114                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8115                        continue;
8116                    }
8117
8118                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8119                    if (!detailed) {
8120                        rti.baseIntent.replaceExtras((Bundle)null);
8121                    }
8122
8123                    res.add(rti);
8124                    maxNum--;
8125                }
8126            }
8127            return res;
8128        }
8129    }
8130
8131    private TaskRecord taskForIdLocked(int id) {
8132        final TaskRecord task = recentTaskForIdLocked(id);
8133        if (task != null) {
8134            return task;
8135        }
8136
8137        // Don't give up. Sometimes it just hasn't made it to recents yet.
8138        return mStackSupervisor.anyTaskForIdLocked(id);
8139    }
8140
8141    private TaskRecord recentTaskForIdLocked(int id) {
8142        final int N = mRecentTasks.size();
8143            for (int i=0; i<N; i++) {
8144                TaskRecord tr = mRecentTasks.get(i);
8145                if (tr.taskId == id) {
8146                    return tr;
8147                }
8148            }
8149            return null;
8150    }
8151
8152    @Override
8153    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8154        synchronized (this) {
8155            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8156                    "getTaskThumbnail()");
8157            TaskRecord tr = recentTaskForIdLocked(id);
8158            if (tr != null) {
8159                return tr.getTaskThumbnailLocked();
8160            }
8161        }
8162        return null;
8163    }
8164
8165    @Override
8166    public int addAppTask(IBinder activityToken, Intent intent,
8167            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8168        final int callingUid = Binder.getCallingUid();
8169        final long callingIdent = Binder.clearCallingIdentity();
8170
8171        try {
8172            synchronized (this) {
8173                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8174                if (r == null) {
8175                    throw new IllegalArgumentException("Activity does not exist; token="
8176                            + activityToken);
8177                }
8178                ComponentName comp = intent.getComponent();
8179                if (comp == null) {
8180                    throw new IllegalArgumentException("Intent " + intent
8181                            + " must specify explicit component");
8182                }
8183                if (thumbnail.getWidth() != mThumbnailWidth
8184                        || thumbnail.getHeight() != mThumbnailHeight) {
8185                    throw new IllegalArgumentException("Bad thumbnail size: got "
8186                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8187                            + mThumbnailWidth + "x" + mThumbnailHeight);
8188                }
8189                if (intent.getSelector() != null) {
8190                    intent.setSelector(null);
8191                }
8192                if (intent.getSourceBounds() != null) {
8193                    intent.setSourceBounds(null);
8194                }
8195                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8196                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8197                        // The caller has added this as an auto-remove task...  that makes no
8198                        // sense, so turn off auto-remove.
8199                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8200                    }
8201                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8202                    // Must be a new task.
8203                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8204                }
8205                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8206                    mLastAddedTaskActivity = null;
8207                }
8208                ActivityInfo ainfo = mLastAddedTaskActivity;
8209                if (ainfo == null) {
8210                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8211                            comp, 0, UserHandle.getUserId(callingUid));
8212                    if (ainfo.applicationInfo.uid != callingUid) {
8213                        throw new SecurityException(
8214                                "Can't add task for another application: target uid="
8215                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8216                    }
8217                }
8218
8219                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8220                        intent, description);
8221
8222                int trimIdx = trimRecentsForTask(task, false);
8223                if (trimIdx >= 0) {
8224                    // If this would have caused a trim, then we'll abort because that
8225                    // means it would be added at the end of the list but then just removed.
8226                    return -1;
8227                }
8228
8229                final int N = mRecentTasks.size();
8230                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8231                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8232                    tr.removedFromRecents(mTaskPersister);
8233                }
8234
8235                task.inRecents = true;
8236                mRecentTasks.add(task);
8237                r.task.stack.addTask(task, false, false);
8238
8239                task.setLastThumbnail(thumbnail);
8240                task.freeLastThumbnail();
8241
8242                return task.taskId;
8243            }
8244        } finally {
8245            Binder.restoreCallingIdentity(callingIdent);
8246        }
8247    }
8248
8249    @Override
8250    public Point getAppTaskThumbnailSize() {
8251        synchronized (this) {
8252            return new Point(mThumbnailWidth,  mThumbnailHeight);
8253        }
8254    }
8255
8256    @Override
8257    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8258        synchronized (this) {
8259            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8260            if (r != null) {
8261                r.setTaskDescription(td);
8262                r.task.updateTaskDescription();
8263            }
8264        }
8265    }
8266
8267    @Override
8268    public Bitmap getTaskDescriptionIcon(String filename) {
8269        if (!FileUtils.isValidExtFilename(filename)
8270                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8271            throw new IllegalArgumentException("Bad filename: " + filename);
8272        }
8273        return mTaskPersister.getTaskDescriptionIcon(filename);
8274    }
8275
8276    @Override
8277    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8278            throws RemoteException {
8279        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8280                opts.getCustomInPlaceResId() == 0) {
8281            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8282                    "with valid animation");
8283        }
8284        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8285        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8286                opts.getCustomInPlaceResId());
8287        mWindowManager.executeAppTransition();
8288    }
8289
8290    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8291        mRecentTasks.remove(tr);
8292        tr.removedFromRecents(mTaskPersister);
8293        ComponentName component = tr.getBaseIntent().getComponent();
8294        if (component == null) {
8295            Slog.w(TAG, "No component for base intent of task: " + tr);
8296            return;
8297        }
8298
8299        if (!killProcess) {
8300            return;
8301        }
8302
8303        // Determine if the process(es) for this task should be killed.
8304        final String pkg = component.getPackageName();
8305        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8306        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8307        for (int i = 0; i < pmap.size(); i++) {
8308
8309            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8310            for (int j = 0; j < uids.size(); j++) {
8311                ProcessRecord proc = uids.valueAt(j);
8312                if (proc.userId != tr.userId) {
8313                    // Don't kill process for a different user.
8314                    continue;
8315                }
8316                if (proc == mHomeProcess) {
8317                    // Don't kill the home process along with tasks from the same package.
8318                    continue;
8319                }
8320                if (!proc.pkgList.containsKey(pkg)) {
8321                    // Don't kill process that is not associated with this task.
8322                    continue;
8323                }
8324
8325                for (int k = 0; k < proc.activities.size(); k++) {
8326                    TaskRecord otherTask = proc.activities.get(k).task;
8327                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8328                        // Don't kill process(es) that has an activity in a different task that is
8329                        // also in recents.
8330                        return;
8331                    }
8332                }
8333
8334                // Add process to kill list.
8335                procsToKill.add(proc);
8336            }
8337        }
8338
8339        // Find any running services associated with this app and stop if needed.
8340        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8341
8342        // Kill the running processes.
8343        for (int i = 0; i < procsToKill.size(); i++) {
8344            ProcessRecord pr = procsToKill.get(i);
8345            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8346                pr.kill("remove task", true);
8347            } else {
8348                pr.waitingToKill = "remove task";
8349            }
8350        }
8351    }
8352
8353    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8354        // Remove all tasks with activities in the specified package from the list of recent tasks
8355        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8356            TaskRecord tr = mRecentTasks.get(i);
8357            if (tr.userId != userId) continue;
8358
8359            ComponentName cn = tr.intent.getComponent();
8360            if (cn != null && cn.getPackageName().equals(packageName)) {
8361                // If the package name matches, remove the task.
8362                removeTaskByIdLocked(tr.taskId, true);
8363            }
8364        }
8365    }
8366
8367    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8368        final IPackageManager pm = AppGlobals.getPackageManager();
8369        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8370
8371        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8372            TaskRecord tr = mRecentTasks.get(i);
8373            if (tr.userId != userId) continue;
8374
8375            ComponentName cn = tr.intent.getComponent();
8376            if (cn != null && cn.getPackageName().equals(packageName)) {
8377                // Skip if component still exists in the package.
8378                if (componentsKnownToExist.contains(cn)) continue;
8379
8380                try {
8381                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8382                    if (info != null) {
8383                        componentsKnownToExist.add(cn);
8384                    } else {
8385                        removeTaskByIdLocked(tr.taskId, false);
8386                    }
8387                } catch (RemoteException e) {
8388                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8389                }
8390            }
8391        }
8392    }
8393
8394    /**
8395     * Removes the task with the specified task id.
8396     *
8397     * @param taskId Identifier of the task to be removed.
8398     * @param killProcess Kill any process associated with the task if possible.
8399     * @return Returns true if the given task was found and removed.
8400     */
8401    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8402        TaskRecord tr = taskForIdLocked(taskId);
8403        if (tr != null) {
8404            tr.removeTaskActivitiesLocked();
8405            cleanUpRemovedTaskLocked(tr, killProcess);
8406            if (tr.isPersistable) {
8407                notifyTaskPersisterLocked(null, true);
8408            }
8409            return true;
8410        }
8411        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8412        return false;
8413    }
8414
8415    @Override
8416    public boolean removeTask(int taskId) {
8417        synchronized (this) {
8418            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8419                    "removeTask()");
8420            long ident = Binder.clearCallingIdentity();
8421            try {
8422                return removeTaskByIdLocked(taskId, true);
8423            } finally {
8424                Binder.restoreCallingIdentity(ident);
8425            }
8426        }
8427    }
8428
8429    /**
8430     * TODO: Add mController hook
8431     */
8432    @Override
8433    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8435                "moveTaskToFront()");
8436
8437        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8438        synchronized(this) {
8439            moveTaskToFrontLocked(taskId, flags, options);
8440        }
8441    }
8442
8443    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8444        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8445                Binder.getCallingUid(), -1, -1, "Task to front")) {
8446            ActivityOptions.abort(options);
8447            return;
8448        }
8449        final long origId = Binder.clearCallingIdentity();
8450        try {
8451            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8452            if (task == null) {
8453                Slog.d(TAG, "Could not find task for id: "+ taskId);
8454                return;
8455            }
8456            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8457                mStackSupervisor.showLockTaskToast();
8458                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8459                return;
8460            }
8461            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8462            if (prev != null && prev.isRecentsActivity()) {
8463                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8464            }
8465            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8466        } finally {
8467            Binder.restoreCallingIdentity(origId);
8468        }
8469        ActivityOptions.abort(options);
8470    }
8471
8472    @Override
8473    public void moveTaskToBack(int taskId) {
8474        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8475                "moveTaskToBack()");
8476
8477        synchronized(this) {
8478            TaskRecord tr = taskForIdLocked(taskId);
8479            if (tr != null) {
8480                if (tr == mStackSupervisor.mLockTaskModeTask) {
8481                    mStackSupervisor.showLockTaskToast();
8482                    return;
8483                }
8484                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8485                ActivityStack stack = tr.stack;
8486                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8487                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8488                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8489                        return;
8490                    }
8491                }
8492                final long origId = Binder.clearCallingIdentity();
8493                try {
8494                    stack.moveTaskToBackLocked(taskId, null);
8495                } finally {
8496                    Binder.restoreCallingIdentity(origId);
8497                }
8498            }
8499        }
8500    }
8501
8502    /**
8503     * Moves an activity, and all of the other activities within the same task, to the bottom
8504     * of the history stack.  The activity's order within the task is unchanged.
8505     *
8506     * @param token A reference to the activity we wish to move
8507     * @param nonRoot If false then this only works if the activity is the root
8508     *                of a task; if true it will work for any activity in a task.
8509     * @return Returns true if the move completed, false if not.
8510     */
8511    @Override
8512    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8513        enforceNotIsolatedCaller("moveActivityTaskToBack");
8514        synchronized(this) {
8515            final long origId = Binder.clearCallingIdentity();
8516            try {
8517                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8518                if (taskId >= 0) {
8519                    if ((mStackSupervisor.mLockTaskModeTask != null)
8520                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8521                        mStackSupervisor.showLockTaskToast();
8522                        return false;
8523                    }
8524                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8525                }
8526            } finally {
8527                Binder.restoreCallingIdentity(origId);
8528            }
8529        }
8530        return false;
8531    }
8532
8533    @Override
8534    public void moveTaskBackwards(int task) {
8535        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8536                "moveTaskBackwards()");
8537
8538        synchronized(this) {
8539            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8540                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8541                return;
8542            }
8543            final long origId = Binder.clearCallingIdentity();
8544            moveTaskBackwardsLocked(task);
8545            Binder.restoreCallingIdentity(origId);
8546        }
8547    }
8548
8549    private final void moveTaskBackwardsLocked(int task) {
8550        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8551    }
8552
8553    @Override
8554    public IBinder getHomeActivityToken() throws RemoteException {
8555        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8556                "getHomeActivityToken()");
8557        synchronized (this) {
8558            return mStackSupervisor.getHomeActivityToken();
8559        }
8560    }
8561
8562    @Override
8563    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8564            IActivityContainerCallback callback) throws RemoteException {
8565        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8566                "createActivityContainer()");
8567        synchronized (this) {
8568            if (parentActivityToken == null) {
8569                throw new IllegalArgumentException("parent token must not be null");
8570            }
8571            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8572            if (r == null) {
8573                return null;
8574            }
8575            if (callback == null) {
8576                throw new IllegalArgumentException("callback must not be null");
8577            }
8578            return mStackSupervisor.createActivityContainer(r, callback);
8579        }
8580    }
8581
8582    @Override
8583    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8584        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8585                "deleteActivityContainer()");
8586        synchronized (this) {
8587            mStackSupervisor.deleteActivityContainer(container);
8588        }
8589    }
8590
8591    @Override
8592    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8593            throws RemoteException {
8594        synchronized (this) {
8595            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8596            if (stack != null) {
8597                return stack.mActivityContainer;
8598            }
8599            return null;
8600        }
8601    }
8602
8603    @Override
8604    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8605        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8606                "moveTaskToStack()");
8607        if (stackId == HOME_STACK_ID) {
8608            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8609                    new RuntimeException("here").fillInStackTrace());
8610        }
8611        synchronized (this) {
8612            long ident = Binder.clearCallingIdentity();
8613            try {
8614                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8615                        + stackId + " toTop=" + toTop);
8616                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8617            } finally {
8618                Binder.restoreCallingIdentity(ident);
8619            }
8620        }
8621    }
8622
8623    @Override
8624    public void resizeStack(int stackBoxId, Rect bounds) {
8625        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8626                "resizeStackBox()");
8627        long ident = Binder.clearCallingIdentity();
8628        try {
8629            mWindowManager.resizeStack(stackBoxId, bounds);
8630        } finally {
8631            Binder.restoreCallingIdentity(ident);
8632        }
8633    }
8634
8635    @Override
8636    public List<StackInfo> getAllStackInfos() {
8637        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8638                "getAllStackInfos()");
8639        long ident = Binder.clearCallingIdentity();
8640        try {
8641            synchronized (this) {
8642                return mStackSupervisor.getAllStackInfosLocked();
8643            }
8644        } finally {
8645            Binder.restoreCallingIdentity(ident);
8646        }
8647    }
8648
8649    @Override
8650    public StackInfo getStackInfo(int stackId) {
8651        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8652                "getStackInfo()");
8653        long ident = Binder.clearCallingIdentity();
8654        try {
8655            synchronized (this) {
8656                return mStackSupervisor.getStackInfoLocked(stackId);
8657            }
8658        } finally {
8659            Binder.restoreCallingIdentity(ident);
8660        }
8661    }
8662
8663    @Override
8664    public boolean isInHomeStack(int taskId) {
8665        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8666                "getStackInfo()");
8667        long ident = Binder.clearCallingIdentity();
8668        try {
8669            synchronized (this) {
8670                TaskRecord tr = taskForIdLocked(taskId);
8671                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8672            }
8673        } finally {
8674            Binder.restoreCallingIdentity(ident);
8675        }
8676    }
8677
8678    @Override
8679    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8680        synchronized(this) {
8681            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8682        }
8683    }
8684
8685    private boolean isLockTaskAuthorized(String pkg) {
8686        final DevicePolicyManager dpm = (DevicePolicyManager)
8687                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8688        try {
8689            int uid = mContext.getPackageManager().getPackageUid(pkg,
8690                    Binder.getCallingUserHandle().getIdentifier());
8691            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8692        } catch (NameNotFoundException e) {
8693            return false;
8694        }
8695    }
8696
8697    void startLockTaskMode(TaskRecord task) {
8698        final String pkg;
8699        synchronized (this) {
8700            pkg = task.intent.getComponent().getPackageName();
8701        }
8702        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8703        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8704            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8705                    StatusBarManagerInternal.class);
8706            if (statusBarManager != null) {
8707                statusBarManager.showScreenPinningRequest();
8708            }
8709            return;
8710        }
8711        long ident = Binder.clearCallingIdentity();
8712        try {
8713            synchronized (this) {
8714                // Since we lost lock on task, make sure it is still there.
8715                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8716                if (task != null) {
8717                    if (!isSystemInitiated
8718                            && ((mStackSupervisor.getFocusedStack() == null)
8719                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8720                        throw new IllegalArgumentException("Invalid task, not in foreground");
8721                    }
8722                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8723                }
8724            }
8725        } finally {
8726            Binder.restoreCallingIdentity(ident);
8727        }
8728    }
8729
8730    @Override
8731    public void startLockTaskMode(int taskId) {
8732        final TaskRecord task;
8733        long ident = Binder.clearCallingIdentity();
8734        try {
8735            synchronized (this) {
8736                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8737            }
8738        } finally {
8739            Binder.restoreCallingIdentity(ident);
8740        }
8741        if (task != null) {
8742            startLockTaskMode(task);
8743        }
8744    }
8745
8746    @Override
8747    public void startLockTaskMode(IBinder token) {
8748        final TaskRecord task;
8749        long ident = Binder.clearCallingIdentity();
8750        try {
8751            synchronized (this) {
8752                final ActivityRecord r = ActivityRecord.forToken(token);
8753                if (r == null) {
8754                    return;
8755                }
8756                task = r.task;
8757            }
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761        if (task != null) {
8762            startLockTaskMode(task);
8763        }
8764    }
8765
8766    @Override
8767    public void startLockTaskModeOnCurrent() throws RemoteException {
8768        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8769                "startLockTaskModeOnCurrent");
8770        long ident = Binder.clearCallingIdentity();
8771        try {
8772            ActivityRecord r = null;
8773            synchronized (this) {
8774                r = mStackSupervisor.topRunningActivityLocked();
8775            }
8776            startLockTaskMode(r.task);
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public void stopLockTaskMode() {
8784        // Verify that the user matches the package of the intent for the TaskRecord
8785        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8786        // and stopLockTaskMode.
8787        final int callingUid = Binder.getCallingUid();
8788        if (callingUid != Process.SYSTEM_UID) {
8789            try {
8790                String pkg =
8791                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8792                int uid = mContext.getPackageManager().getPackageUid(pkg,
8793                        Binder.getCallingUserHandle().getIdentifier());
8794                if (uid != callingUid) {
8795                    throw new SecurityException("Invalid uid, expected " + uid);
8796                }
8797            } catch (NameNotFoundException e) {
8798                Log.d(TAG, "stopLockTaskMode " + e);
8799                return;
8800            }
8801        }
8802        long ident = Binder.clearCallingIdentity();
8803        try {
8804            Log.d(TAG, "stopLockTaskMode");
8805            // Stop lock task
8806            synchronized (this) {
8807                mStackSupervisor.setLockTaskModeLocked(null, false);
8808            }
8809        } finally {
8810            Binder.restoreCallingIdentity(ident);
8811        }
8812    }
8813
8814    @Override
8815    public void stopLockTaskModeOnCurrent() throws RemoteException {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "stopLockTaskModeOnCurrent");
8818        long ident = Binder.clearCallingIdentity();
8819        try {
8820            stopLockTaskMode();
8821        } finally {
8822            Binder.restoreCallingIdentity(ident);
8823        }
8824    }
8825
8826    @Override
8827    public boolean isInLockTaskMode() {
8828        synchronized (this) {
8829            return mStackSupervisor.isInLockTaskMode();
8830        }
8831    }
8832
8833    // =========================================================
8834    // CONTENT PROVIDERS
8835    // =========================================================
8836
8837    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8838        List<ProviderInfo> providers = null;
8839        try {
8840            providers = AppGlobals.getPackageManager().
8841                queryContentProviders(app.processName, app.uid,
8842                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8843        } catch (RemoteException ex) {
8844        }
8845        if (DEBUG_MU)
8846            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8847        int userId = app.userId;
8848        if (providers != null) {
8849            int N = providers.size();
8850            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8851            for (int i=0; i<N; i++) {
8852                ProviderInfo cpi =
8853                    (ProviderInfo)providers.get(i);
8854                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8855                        cpi.name, cpi.flags);
8856                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8857                    // This is a singleton provider, but a user besides the
8858                    // default user is asking to initialize a process it runs
8859                    // in...  well, no, it doesn't actually run in this process,
8860                    // it runs in the process of the default user.  Get rid of it.
8861                    providers.remove(i);
8862                    N--;
8863                    i--;
8864                    continue;
8865                }
8866
8867                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8868                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8869                if (cpr == null) {
8870                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8871                    mProviderMap.putProviderByClass(comp, cpr);
8872                }
8873                if (DEBUG_MU)
8874                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8875                app.pubProviders.put(cpi.name, cpr);
8876                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8877                    // Don't add this if it is a platform component that is marked
8878                    // to run in multiple processes, because this is actually
8879                    // part of the framework so doesn't make sense to track as a
8880                    // separate apk in the process.
8881                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8882                            mProcessStats);
8883                }
8884                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8885            }
8886        }
8887        return providers;
8888    }
8889
8890    /**
8891     * Check if {@link ProcessRecord} has a possible chance at accessing the
8892     * given {@link ProviderInfo}. Final permission checking is always done
8893     * in {@link ContentProvider}.
8894     */
8895    private final String checkContentProviderPermissionLocked(
8896            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8897        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8898        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8899        boolean checkedGrants = false;
8900        if (checkUser) {
8901            // Looking for cross-user grants before enforcing the typical cross-users permissions
8902            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8903            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8904                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8905                    return null;
8906                }
8907                checkedGrants = true;
8908            }
8909            userId = handleIncomingUser(callingPid, callingUid, userId,
8910                    false, ALLOW_NON_FULL,
8911                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8912            if (userId != tmpTargetUserId) {
8913                // When we actually went to determine the final targer user ID, this ended
8914                // up different than our initial check for the authority.  This is because
8915                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8916                // SELF.  So we need to re-check the grants again.
8917                checkedGrants = false;
8918            }
8919        }
8920        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8921                cpi.applicationInfo.uid, cpi.exported)
8922                == PackageManager.PERMISSION_GRANTED) {
8923            return null;
8924        }
8925        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8926                cpi.applicationInfo.uid, cpi.exported)
8927                == PackageManager.PERMISSION_GRANTED) {
8928            return null;
8929        }
8930
8931        PathPermission[] pps = cpi.pathPermissions;
8932        if (pps != null) {
8933            int i = pps.length;
8934            while (i > 0) {
8935                i--;
8936                PathPermission pp = pps[i];
8937                String pprperm = pp.getReadPermission();
8938                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8939                        cpi.applicationInfo.uid, cpi.exported)
8940                        == PackageManager.PERMISSION_GRANTED) {
8941                    return null;
8942                }
8943                String ppwperm = pp.getWritePermission();
8944                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8945                        cpi.applicationInfo.uid, cpi.exported)
8946                        == PackageManager.PERMISSION_GRANTED) {
8947                    return null;
8948                }
8949            }
8950        }
8951        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8952            return null;
8953        }
8954
8955        String msg;
8956        if (!cpi.exported) {
8957            msg = "Permission Denial: opening provider " + cpi.name
8958                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8959                    + ", uid=" + callingUid + ") that is not exported from uid "
8960                    + cpi.applicationInfo.uid;
8961        } else {
8962            msg = "Permission Denial: opening provider " + cpi.name
8963                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8964                    + ", uid=" + callingUid + ") requires "
8965                    + cpi.readPermission + " or " + cpi.writePermission;
8966        }
8967        Slog.w(TAG, msg);
8968        return msg;
8969    }
8970
8971    /**
8972     * Returns if the ContentProvider has granted a uri to callingUid
8973     */
8974    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8975        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8976        if (perms != null) {
8977            for (int i=perms.size()-1; i>=0; i--) {
8978                GrantUri grantUri = perms.keyAt(i);
8979                if (grantUri.sourceUserId == userId || !checkUser) {
8980                    if (matchesProvider(grantUri.uri, cpi)) {
8981                        return true;
8982                    }
8983                }
8984            }
8985        }
8986        return false;
8987    }
8988
8989    /**
8990     * Returns true if the uri authority is one of the authorities specified in the provider.
8991     */
8992    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8993        String uriAuth = uri.getAuthority();
8994        String cpiAuth = cpi.authority;
8995        if (cpiAuth.indexOf(';') == -1) {
8996            return cpiAuth.equals(uriAuth);
8997        }
8998        String[] cpiAuths = cpiAuth.split(";");
8999        int length = cpiAuths.length;
9000        for (int i = 0; i < length; i++) {
9001            if (cpiAuths[i].equals(uriAuth)) return true;
9002        }
9003        return false;
9004    }
9005
9006    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9007            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9008        if (r != null) {
9009            for (int i=0; i<r.conProviders.size(); i++) {
9010                ContentProviderConnection conn = r.conProviders.get(i);
9011                if (conn.provider == cpr) {
9012                    if (DEBUG_PROVIDER) Slog.v(TAG,
9013                            "Adding provider requested by "
9014                            + r.processName + " from process "
9015                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9016                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9017                    if (stable) {
9018                        conn.stableCount++;
9019                        conn.numStableIncs++;
9020                    } else {
9021                        conn.unstableCount++;
9022                        conn.numUnstableIncs++;
9023                    }
9024                    return conn;
9025                }
9026            }
9027            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9028            if (stable) {
9029                conn.stableCount = 1;
9030                conn.numStableIncs = 1;
9031            } else {
9032                conn.unstableCount = 1;
9033                conn.numUnstableIncs = 1;
9034            }
9035            cpr.connections.add(conn);
9036            r.conProviders.add(conn);
9037            return conn;
9038        }
9039        cpr.addExternalProcessHandleLocked(externalProcessToken);
9040        return null;
9041    }
9042
9043    boolean decProviderCountLocked(ContentProviderConnection conn,
9044            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9045        if (conn != null) {
9046            cpr = conn.provider;
9047            if (DEBUG_PROVIDER) Slog.v(TAG,
9048                    "Removing provider requested by "
9049                    + conn.client.processName + " from process "
9050                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9051                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9052            if (stable) {
9053                conn.stableCount--;
9054            } else {
9055                conn.unstableCount--;
9056            }
9057            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9058                cpr.connections.remove(conn);
9059                conn.client.conProviders.remove(conn);
9060                return true;
9061            }
9062            return false;
9063        }
9064        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9065        return false;
9066    }
9067
9068    private void checkTime(long startTime, String where) {
9069        long now = SystemClock.elapsedRealtime();
9070        if ((now-startTime) > 1000) {
9071            // If we are taking more than a second, log about it.
9072            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9073        }
9074    }
9075
9076    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9077            String name, IBinder token, boolean stable, int userId) {
9078        ContentProviderRecord cpr;
9079        ContentProviderConnection conn = null;
9080        ProviderInfo cpi = null;
9081
9082        synchronized(this) {
9083            long startTime = SystemClock.elapsedRealtime();
9084
9085            ProcessRecord r = null;
9086            if (caller != null) {
9087                r = getRecordForAppLocked(caller);
9088                if (r == null) {
9089                    throw new SecurityException(
9090                            "Unable to find app for caller " + caller
9091                          + " (pid=" + Binder.getCallingPid()
9092                          + ") when getting content provider " + name);
9093                }
9094            }
9095
9096            boolean checkCrossUser = true;
9097
9098            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9099
9100            // First check if this content provider has been published...
9101            cpr = mProviderMap.getProviderByName(name, userId);
9102            // If that didn't work, check if it exists for user 0 and then
9103            // verify that it's a singleton provider before using it.
9104            if (cpr == null && userId != UserHandle.USER_OWNER) {
9105                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9106                if (cpr != null) {
9107                    cpi = cpr.info;
9108                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9109                            cpi.name, cpi.flags)
9110                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9111                        userId = UserHandle.USER_OWNER;
9112                        checkCrossUser = false;
9113                    } else {
9114                        cpr = null;
9115                        cpi = null;
9116                    }
9117                }
9118            }
9119
9120            boolean providerRunning = cpr != null;
9121            if (providerRunning) {
9122                cpi = cpr.info;
9123                String msg;
9124                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9125                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9126                        != null) {
9127                    throw new SecurityException(msg);
9128                }
9129                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9130
9131                if (r != null && cpr.canRunHere(r)) {
9132                    // This provider has been published or is in the process
9133                    // of being published...  but it is also allowed to run
9134                    // in the caller's process, so don't make a connection
9135                    // and just let the caller instantiate its own instance.
9136                    ContentProviderHolder holder = cpr.newHolder(null);
9137                    // don't give caller the provider object, it needs
9138                    // to make its own.
9139                    holder.provider = null;
9140                    return holder;
9141                }
9142
9143                final long origId = Binder.clearCallingIdentity();
9144
9145                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9146
9147                // In this case the provider instance already exists, so we can
9148                // return it right away.
9149                conn = incProviderCountLocked(r, cpr, token, stable);
9150                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9151                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9152                        // If this is a perceptible app accessing the provider,
9153                        // make sure to count it as being accessed and thus
9154                        // back up on the LRU list.  This is good because
9155                        // content providers are often expensive to start.
9156                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9157                        updateLruProcessLocked(cpr.proc, false, null);
9158                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9159                    }
9160                }
9161
9162                if (cpr.proc != null) {
9163                    if (false) {
9164                        if (cpr.name.flattenToShortString().equals(
9165                                "com.android.providers.calendar/.CalendarProvider2")) {
9166                            Slog.v(TAG, "****************** KILLING "
9167                                + cpr.name.flattenToShortString());
9168                            Process.killProcess(cpr.proc.pid);
9169                        }
9170                    }
9171                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9172                    boolean success = updateOomAdjLocked(cpr.proc);
9173                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9174                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9175                    // NOTE: there is still a race here where a signal could be
9176                    // pending on the process even though we managed to update its
9177                    // adj level.  Not sure what to do about this, but at least
9178                    // the race is now smaller.
9179                    if (!success) {
9180                        // Uh oh...  it looks like the provider's process
9181                        // has been killed on us.  We need to wait for a new
9182                        // process to be started, and make sure its death
9183                        // doesn't kill our process.
9184                        Slog.i(TAG,
9185                                "Existing provider " + cpr.name.flattenToShortString()
9186                                + " is crashing; detaching " + r);
9187                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9188                        checkTime(startTime, "getContentProviderImpl: before appDied");
9189                        appDiedLocked(cpr.proc);
9190                        checkTime(startTime, "getContentProviderImpl: after appDied");
9191                        if (!lastRef) {
9192                            // This wasn't the last ref our process had on
9193                            // the provider...  we have now been killed, bail.
9194                            return null;
9195                        }
9196                        providerRunning = false;
9197                        conn = null;
9198                    }
9199                }
9200
9201                Binder.restoreCallingIdentity(origId);
9202            }
9203
9204            boolean singleton;
9205            if (!providerRunning) {
9206                try {
9207                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9208                    cpi = AppGlobals.getPackageManager().
9209                        resolveContentProvider(name,
9210                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9211                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9212                } catch (RemoteException ex) {
9213                }
9214                if (cpi == null) {
9215                    return null;
9216                }
9217                // If the provider is a singleton AND
9218                // (it's a call within the same user || the provider is a
9219                // privileged app)
9220                // Then allow connecting to the singleton provider
9221                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9222                        cpi.name, cpi.flags)
9223                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9224                if (singleton) {
9225                    userId = UserHandle.USER_OWNER;
9226                }
9227                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9228                checkTime(startTime, "getContentProviderImpl: got app info for user");
9229
9230                String msg;
9231                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9232                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9233                        != null) {
9234                    throw new SecurityException(msg);
9235                }
9236                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9237
9238                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9239                        && !cpi.processName.equals("system")) {
9240                    // If this content provider does not run in the system
9241                    // process, and the system is not yet ready to run other
9242                    // processes, then fail fast instead of hanging.
9243                    throw new IllegalArgumentException(
9244                            "Attempt to launch content provider before system ready");
9245                }
9246
9247                // Make sure that the user who owns this provider is started.  If not,
9248                // we don't want to allow it to run.
9249                if (mStartedUsers.get(userId) == null) {
9250                    Slog.w(TAG, "Unable to launch app "
9251                            + cpi.applicationInfo.packageName + "/"
9252                            + cpi.applicationInfo.uid + " for provider "
9253                            + name + ": user " + userId + " is stopped");
9254                    return null;
9255                }
9256
9257                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9258                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9259                cpr = mProviderMap.getProviderByClass(comp, userId);
9260                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9261                final boolean firstClass = cpr == null;
9262                if (firstClass) {
9263                    final long ident = Binder.clearCallingIdentity();
9264                    try {
9265                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9266                        ApplicationInfo ai =
9267                            AppGlobals.getPackageManager().
9268                                getApplicationInfo(
9269                                        cpi.applicationInfo.packageName,
9270                                        STOCK_PM_FLAGS, userId);
9271                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9272                        if (ai == null) {
9273                            Slog.w(TAG, "No package info for content provider "
9274                                    + cpi.name);
9275                            return null;
9276                        }
9277                        ai = getAppInfoForUser(ai, userId);
9278                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9279                    } catch (RemoteException ex) {
9280                        // pm is in same process, this will never happen.
9281                    } finally {
9282                        Binder.restoreCallingIdentity(ident);
9283                    }
9284                }
9285
9286                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9287
9288                if (r != null && cpr.canRunHere(r)) {
9289                    // If this is a multiprocess provider, then just return its
9290                    // info and allow the caller to instantiate it.  Only do
9291                    // this if the provider is the same user as the caller's
9292                    // process, or can run as root (so can be in any process).
9293                    return cpr.newHolder(null);
9294                }
9295
9296                if (DEBUG_PROVIDER) {
9297                    RuntimeException e = new RuntimeException("here");
9298                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9299                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9300                }
9301
9302                // This is single process, and our app is now connecting to it.
9303                // See if we are already in the process of launching this
9304                // provider.
9305                final int N = mLaunchingProviders.size();
9306                int i;
9307                for (i=0; i<N; i++) {
9308                    if (mLaunchingProviders.get(i) == cpr) {
9309                        break;
9310                    }
9311                }
9312
9313                // If the provider is not already being launched, then get it
9314                // started.
9315                if (i >= N) {
9316                    final long origId = Binder.clearCallingIdentity();
9317
9318                    try {
9319                        // Content provider is now in use, its package can't be stopped.
9320                        try {
9321                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9322                            AppGlobals.getPackageManager().setPackageStoppedState(
9323                                    cpr.appInfo.packageName, false, userId);
9324                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9325                        } catch (RemoteException e) {
9326                        } catch (IllegalArgumentException e) {
9327                            Slog.w(TAG, "Failed trying to unstop package "
9328                                    + cpr.appInfo.packageName + ": " + e);
9329                        }
9330
9331                        // Use existing process if already started
9332                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9333                        ProcessRecord proc = getProcessRecordLocked(
9334                                cpi.processName, cpr.appInfo.uid, false);
9335                        if (proc != null && proc.thread != null) {
9336                            if (DEBUG_PROVIDER) {
9337                                Slog.d(TAG, "Installing in existing process " + proc);
9338                            }
9339                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9340                            proc.pubProviders.put(cpi.name, cpr);
9341                            try {
9342                                proc.thread.scheduleInstallProvider(cpi);
9343                            } catch (RemoteException e) {
9344                            }
9345                        } else {
9346                            checkTime(startTime, "getContentProviderImpl: before start process");
9347                            proc = startProcessLocked(cpi.processName,
9348                                    cpr.appInfo, false, 0, "content provider",
9349                                    new ComponentName(cpi.applicationInfo.packageName,
9350                                            cpi.name), false, false, false);
9351                            checkTime(startTime, "getContentProviderImpl: after start process");
9352                            if (proc == null) {
9353                                Slog.w(TAG, "Unable to launch app "
9354                                        + cpi.applicationInfo.packageName + "/"
9355                                        + cpi.applicationInfo.uid + " for provider "
9356                                        + name + ": process is bad");
9357                                return null;
9358                            }
9359                        }
9360                        cpr.launchingApp = proc;
9361                        mLaunchingProviders.add(cpr);
9362                    } finally {
9363                        Binder.restoreCallingIdentity(origId);
9364                    }
9365                }
9366
9367                checkTime(startTime, "getContentProviderImpl: updating data structures");
9368
9369                // Make sure the provider is published (the same provider class
9370                // may be published under multiple names).
9371                if (firstClass) {
9372                    mProviderMap.putProviderByClass(comp, cpr);
9373                }
9374
9375                mProviderMap.putProviderByName(name, cpr);
9376                conn = incProviderCountLocked(r, cpr, token, stable);
9377                if (conn != null) {
9378                    conn.waiting = true;
9379                }
9380            }
9381            checkTime(startTime, "getContentProviderImpl: done!");
9382        }
9383
9384        // Wait for the provider to be published...
9385        synchronized (cpr) {
9386            while (cpr.provider == null) {
9387                if (cpr.launchingApp == null) {
9388                    Slog.w(TAG, "Unable to launch app "
9389                            + cpi.applicationInfo.packageName + "/"
9390                            + cpi.applicationInfo.uid + " for provider "
9391                            + name + ": launching app became null");
9392                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9393                            UserHandle.getUserId(cpi.applicationInfo.uid),
9394                            cpi.applicationInfo.packageName,
9395                            cpi.applicationInfo.uid, name);
9396                    return null;
9397                }
9398                try {
9399                    if (DEBUG_MU) {
9400                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9401                                + cpr.launchingApp);
9402                    }
9403                    if (conn != null) {
9404                        conn.waiting = true;
9405                    }
9406                    cpr.wait();
9407                } catch (InterruptedException ex) {
9408                } finally {
9409                    if (conn != null) {
9410                        conn.waiting = false;
9411                    }
9412                }
9413            }
9414        }
9415        return cpr != null ? cpr.newHolder(conn) : null;
9416    }
9417
9418    @Override
9419    public final ContentProviderHolder getContentProvider(
9420            IApplicationThread caller, String name, int userId, boolean stable) {
9421        enforceNotIsolatedCaller("getContentProvider");
9422        if (caller == null) {
9423            String msg = "null IApplicationThread when getting content provider "
9424                    + name;
9425            Slog.w(TAG, msg);
9426            throw new SecurityException(msg);
9427        }
9428        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9429        // with cross-user grant.
9430        return getContentProviderImpl(caller, name, null, stable, userId);
9431    }
9432
9433    public ContentProviderHolder getContentProviderExternal(
9434            String name, int userId, IBinder token) {
9435        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9436            "Do not have permission in call getContentProviderExternal()");
9437        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9438                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9439        return getContentProviderExternalUnchecked(name, token, userId);
9440    }
9441
9442    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9443            IBinder token, int userId) {
9444        return getContentProviderImpl(null, name, token, true, userId);
9445    }
9446
9447    /**
9448     * Drop a content provider from a ProcessRecord's bookkeeping
9449     */
9450    public void removeContentProvider(IBinder connection, boolean stable) {
9451        enforceNotIsolatedCaller("removeContentProvider");
9452        long ident = Binder.clearCallingIdentity();
9453        try {
9454            synchronized (this) {
9455                ContentProviderConnection conn;
9456                try {
9457                    conn = (ContentProviderConnection)connection;
9458                } catch (ClassCastException e) {
9459                    String msg ="removeContentProvider: " + connection
9460                            + " not a ContentProviderConnection";
9461                    Slog.w(TAG, msg);
9462                    throw new IllegalArgumentException(msg);
9463                }
9464                if (conn == null) {
9465                    throw new NullPointerException("connection is null");
9466                }
9467                if (decProviderCountLocked(conn, null, null, stable)) {
9468                    updateOomAdjLocked();
9469                }
9470            }
9471        } finally {
9472            Binder.restoreCallingIdentity(ident);
9473        }
9474    }
9475
9476    public void removeContentProviderExternal(String name, IBinder token) {
9477        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9478            "Do not have permission in call removeContentProviderExternal()");
9479        int userId = UserHandle.getCallingUserId();
9480        long ident = Binder.clearCallingIdentity();
9481        try {
9482            removeContentProviderExternalUnchecked(name, token, userId);
9483        } finally {
9484            Binder.restoreCallingIdentity(ident);
9485        }
9486    }
9487
9488    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9489        synchronized (this) {
9490            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9491            if(cpr == null) {
9492                //remove from mProvidersByClass
9493                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9494                return;
9495            }
9496
9497            //update content provider record entry info
9498            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9499            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9500            if (localCpr.hasExternalProcessHandles()) {
9501                if (localCpr.removeExternalProcessHandleLocked(token)) {
9502                    updateOomAdjLocked();
9503                } else {
9504                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9505                            + " with no external reference for token: "
9506                            + token + ".");
9507                }
9508            } else {
9509                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9510                        + " with no external references.");
9511            }
9512        }
9513    }
9514
9515    public final void publishContentProviders(IApplicationThread caller,
9516            List<ContentProviderHolder> providers) {
9517        if (providers == null) {
9518            return;
9519        }
9520
9521        enforceNotIsolatedCaller("publishContentProviders");
9522        synchronized (this) {
9523            final ProcessRecord r = getRecordForAppLocked(caller);
9524            if (DEBUG_MU)
9525                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9526            if (r == null) {
9527                throw new SecurityException(
9528                        "Unable to find app for caller " + caller
9529                      + " (pid=" + Binder.getCallingPid()
9530                      + ") when publishing content providers");
9531            }
9532
9533            final long origId = Binder.clearCallingIdentity();
9534
9535            final int N = providers.size();
9536            for (int i=0; i<N; i++) {
9537                ContentProviderHolder src = providers.get(i);
9538                if (src == null || src.info == null || src.provider == null) {
9539                    continue;
9540                }
9541                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9542                if (DEBUG_MU)
9543                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9544                if (dst != null) {
9545                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9546                    mProviderMap.putProviderByClass(comp, dst);
9547                    String names[] = dst.info.authority.split(";");
9548                    for (int j = 0; j < names.length; j++) {
9549                        mProviderMap.putProviderByName(names[j], dst);
9550                    }
9551
9552                    int NL = mLaunchingProviders.size();
9553                    int j;
9554                    for (j=0; j<NL; j++) {
9555                        if (mLaunchingProviders.get(j) == dst) {
9556                            mLaunchingProviders.remove(j);
9557                            j--;
9558                            NL--;
9559                        }
9560                    }
9561                    synchronized (dst) {
9562                        dst.provider = src.provider;
9563                        dst.proc = r;
9564                        dst.notifyAll();
9565                    }
9566                    updateOomAdjLocked(r);
9567                }
9568            }
9569
9570            Binder.restoreCallingIdentity(origId);
9571        }
9572    }
9573
9574    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9575        ContentProviderConnection conn;
9576        try {
9577            conn = (ContentProviderConnection)connection;
9578        } catch (ClassCastException e) {
9579            String msg ="refContentProvider: " + connection
9580                    + " not a ContentProviderConnection";
9581            Slog.w(TAG, msg);
9582            throw new IllegalArgumentException(msg);
9583        }
9584        if (conn == null) {
9585            throw new NullPointerException("connection is null");
9586        }
9587
9588        synchronized (this) {
9589            if (stable > 0) {
9590                conn.numStableIncs += stable;
9591            }
9592            stable = conn.stableCount + stable;
9593            if (stable < 0) {
9594                throw new IllegalStateException("stableCount < 0: " + stable);
9595            }
9596
9597            if (unstable > 0) {
9598                conn.numUnstableIncs += unstable;
9599            }
9600            unstable = conn.unstableCount + unstable;
9601            if (unstable < 0) {
9602                throw new IllegalStateException("unstableCount < 0: " + unstable);
9603            }
9604
9605            if ((stable+unstable) <= 0) {
9606                throw new IllegalStateException("ref counts can't go to zero here: stable="
9607                        + stable + " unstable=" + unstable);
9608            }
9609            conn.stableCount = stable;
9610            conn.unstableCount = unstable;
9611            return !conn.dead;
9612        }
9613    }
9614
9615    public void unstableProviderDied(IBinder connection) {
9616        ContentProviderConnection conn;
9617        try {
9618            conn = (ContentProviderConnection)connection;
9619        } catch (ClassCastException e) {
9620            String msg ="refContentProvider: " + connection
9621                    + " not a ContentProviderConnection";
9622            Slog.w(TAG, msg);
9623            throw new IllegalArgumentException(msg);
9624        }
9625        if (conn == null) {
9626            throw new NullPointerException("connection is null");
9627        }
9628
9629        // Safely retrieve the content provider associated with the connection.
9630        IContentProvider provider;
9631        synchronized (this) {
9632            provider = conn.provider.provider;
9633        }
9634
9635        if (provider == null) {
9636            // Um, yeah, we're way ahead of you.
9637            return;
9638        }
9639
9640        // Make sure the caller is being honest with us.
9641        if (provider.asBinder().pingBinder()) {
9642            // Er, no, still looks good to us.
9643            synchronized (this) {
9644                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9645                        + " says " + conn + " died, but we don't agree");
9646                return;
9647            }
9648        }
9649
9650        // Well look at that!  It's dead!
9651        synchronized (this) {
9652            if (conn.provider.provider != provider) {
9653                // But something changed...  good enough.
9654                return;
9655            }
9656
9657            ProcessRecord proc = conn.provider.proc;
9658            if (proc == null || proc.thread == null) {
9659                // Seems like the process is already cleaned up.
9660                return;
9661            }
9662
9663            // As far as we're concerned, this is just like receiving a
9664            // death notification...  just a bit prematurely.
9665            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9666                    + ") early provider death");
9667            final long ident = Binder.clearCallingIdentity();
9668            try {
9669                appDiedLocked(proc);
9670            } finally {
9671                Binder.restoreCallingIdentity(ident);
9672            }
9673        }
9674    }
9675
9676    @Override
9677    public void appNotRespondingViaProvider(IBinder connection) {
9678        enforceCallingPermission(
9679                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9680
9681        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9682        if (conn == null) {
9683            Slog.w(TAG, "ContentProviderConnection is null");
9684            return;
9685        }
9686
9687        final ProcessRecord host = conn.provider.proc;
9688        if (host == null) {
9689            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9690            return;
9691        }
9692
9693        final long token = Binder.clearCallingIdentity();
9694        try {
9695            appNotResponding(host, null, null, false, "ContentProvider not responding");
9696        } finally {
9697            Binder.restoreCallingIdentity(token);
9698        }
9699    }
9700
9701    public final void installSystemProviders() {
9702        List<ProviderInfo> providers;
9703        synchronized (this) {
9704            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9705            providers = generateApplicationProvidersLocked(app);
9706            if (providers != null) {
9707                for (int i=providers.size()-1; i>=0; i--) {
9708                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9709                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9710                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9711                                + ": not system .apk");
9712                        providers.remove(i);
9713                    }
9714                }
9715            }
9716        }
9717        if (providers != null) {
9718            mSystemThread.installSystemProviders(providers);
9719        }
9720
9721        mCoreSettingsObserver = new CoreSettingsObserver(this);
9722
9723        //mUsageStatsService.monitorPackages();
9724    }
9725
9726    /**
9727     * Allows apps to retrieve the MIME type of a URI.
9728     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9729     * users, then it does not need permission to access the ContentProvider.
9730     * Either, it needs cross-user uri grants.
9731     *
9732     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9733     *
9734     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9735     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9736     */
9737    public String getProviderMimeType(Uri uri, int userId) {
9738        enforceNotIsolatedCaller("getProviderMimeType");
9739        final String name = uri.getAuthority();
9740        int callingUid = Binder.getCallingUid();
9741        int callingPid = Binder.getCallingPid();
9742        long ident = 0;
9743        boolean clearedIdentity = false;
9744        userId = unsafeConvertIncomingUser(userId);
9745        if (canClearIdentity(callingPid, callingUid, userId)) {
9746            clearedIdentity = true;
9747            ident = Binder.clearCallingIdentity();
9748        }
9749        ContentProviderHolder holder = null;
9750        try {
9751            holder = getContentProviderExternalUnchecked(name, null, userId);
9752            if (holder != null) {
9753                return holder.provider.getType(uri);
9754            }
9755        } catch (RemoteException e) {
9756            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9757            return null;
9758        } finally {
9759            // We need to clear the identity to call removeContentProviderExternalUnchecked
9760            if (!clearedIdentity) {
9761                ident = Binder.clearCallingIdentity();
9762            }
9763            try {
9764                if (holder != null) {
9765                    removeContentProviderExternalUnchecked(name, null, userId);
9766                }
9767            } finally {
9768                Binder.restoreCallingIdentity(ident);
9769            }
9770        }
9771
9772        return null;
9773    }
9774
9775    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9776        if (UserHandle.getUserId(callingUid) == userId) {
9777            return true;
9778        }
9779        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9780                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9781                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9782                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9783                return true;
9784        }
9785        return false;
9786    }
9787
9788    // =========================================================
9789    // GLOBAL MANAGEMENT
9790    // =========================================================
9791
9792    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9793            boolean isolated, int isolatedUid) {
9794        String proc = customProcess != null ? customProcess : info.processName;
9795        BatteryStatsImpl.Uid.Proc ps = null;
9796        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9797        int uid = info.uid;
9798        if (isolated) {
9799            if (isolatedUid == 0) {
9800                int userId = UserHandle.getUserId(uid);
9801                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9802                while (true) {
9803                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9804                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9805                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9806                    }
9807                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9808                    mNextIsolatedProcessUid++;
9809                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9810                        // No process for this uid, use it.
9811                        break;
9812                    }
9813                    stepsLeft--;
9814                    if (stepsLeft <= 0) {
9815                        return null;
9816                    }
9817                }
9818            } else {
9819                // Special case for startIsolatedProcess (internal only), where
9820                // the uid of the isolated process is specified by the caller.
9821                uid = isolatedUid;
9822            }
9823        }
9824        return new ProcessRecord(stats, info, proc, uid);
9825    }
9826
9827    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9828            String abiOverride) {
9829        ProcessRecord app;
9830        if (!isolated) {
9831            app = getProcessRecordLocked(info.processName, info.uid, true);
9832        } else {
9833            app = null;
9834        }
9835
9836        if (app == null) {
9837            app = newProcessRecordLocked(info, null, isolated, 0);
9838            mProcessNames.put(info.processName, app.uid, app);
9839            if (isolated) {
9840                mIsolatedProcesses.put(app.uid, app);
9841            }
9842            updateLruProcessLocked(app, false, null);
9843            updateOomAdjLocked();
9844        }
9845
9846        // This package really, really can not be stopped.
9847        try {
9848            AppGlobals.getPackageManager().setPackageStoppedState(
9849                    info.packageName, false, UserHandle.getUserId(app.uid));
9850        } catch (RemoteException e) {
9851        } catch (IllegalArgumentException e) {
9852            Slog.w(TAG, "Failed trying to unstop package "
9853                    + info.packageName + ": " + e);
9854        }
9855
9856        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9857                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9858            app.persistent = true;
9859            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9860        }
9861        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9862            mPersistentStartingProcesses.add(app);
9863            startProcessLocked(app, "added application", app.processName, abiOverride,
9864                    null /* entryPoint */, null /* entryPointArgs */);
9865        }
9866
9867        return app;
9868    }
9869
9870    public void unhandledBack() {
9871        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9872                "unhandledBack()");
9873
9874        synchronized(this) {
9875            final long origId = Binder.clearCallingIdentity();
9876            try {
9877                getFocusedStack().unhandledBackLocked();
9878            } finally {
9879                Binder.restoreCallingIdentity(origId);
9880            }
9881        }
9882    }
9883
9884    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9885        enforceNotIsolatedCaller("openContentUri");
9886        final int userId = UserHandle.getCallingUserId();
9887        String name = uri.getAuthority();
9888        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9889        ParcelFileDescriptor pfd = null;
9890        if (cph != null) {
9891            // We record the binder invoker's uid in thread-local storage before
9892            // going to the content provider to open the file.  Later, in the code
9893            // that handles all permissions checks, we look for this uid and use
9894            // that rather than the Activity Manager's own uid.  The effect is that
9895            // we do the check against the caller's permissions even though it looks
9896            // to the content provider like the Activity Manager itself is making
9897            // the request.
9898            Binder token = new Binder();
9899            sCallerIdentity.set(new Identity(
9900                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9901            try {
9902                pfd = cph.provider.openFile(null, uri, "r", null, token);
9903            } catch (FileNotFoundException e) {
9904                // do nothing; pfd will be returned null
9905            } finally {
9906                // Ensure that whatever happens, we clean up the identity state
9907                sCallerIdentity.remove();
9908            }
9909
9910            // We've got the fd now, so we're done with the provider.
9911            removeContentProviderExternalUnchecked(name, null, userId);
9912        } else {
9913            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9914        }
9915        return pfd;
9916    }
9917
9918    // Actually is sleeping or shutting down or whatever else in the future
9919    // is an inactive state.
9920    public boolean isSleepingOrShuttingDown() {
9921        return isSleeping() || mShuttingDown;
9922    }
9923
9924    public boolean isSleeping() {
9925        return mSleeping;
9926    }
9927
9928    void goingToSleep() {
9929        synchronized(this) {
9930            mWentToSleep = true;
9931            goToSleepIfNeededLocked();
9932        }
9933    }
9934
9935    void finishRunningVoiceLocked() {
9936        if (mRunningVoice) {
9937            mRunningVoice = false;
9938            goToSleepIfNeededLocked();
9939        }
9940    }
9941
9942    void goToSleepIfNeededLocked() {
9943        if (mWentToSleep && !mRunningVoice) {
9944            if (!mSleeping) {
9945                mSleeping = true;
9946                mStackSupervisor.goingToSleepLocked();
9947
9948                // Initialize the wake times of all processes.
9949                checkExcessivePowerUsageLocked(false);
9950                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9951                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9952                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9953            }
9954        }
9955    }
9956
9957    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9958        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9959            // Never persist the home stack.
9960            return;
9961        }
9962        mTaskPersister.wakeup(task, flush);
9963    }
9964
9965    @Override
9966    public boolean shutdown(int timeout) {
9967        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9968                != PackageManager.PERMISSION_GRANTED) {
9969            throw new SecurityException("Requires permission "
9970                    + android.Manifest.permission.SHUTDOWN);
9971        }
9972
9973        boolean timedout = false;
9974
9975        synchronized(this) {
9976            mShuttingDown = true;
9977            updateEventDispatchingLocked();
9978            timedout = mStackSupervisor.shutdownLocked(timeout);
9979        }
9980
9981        mAppOpsService.shutdown();
9982        if (mUsageStatsService != null) {
9983            mUsageStatsService.prepareShutdown();
9984        }
9985        mBatteryStatsService.shutdown();
9986        synchronized (this) {
9987            mProcessStats.shutdownLocked();
9988        }
9989        notifyTaskPersisterLocked(null, true);
9990
9991        return timedout;
9992    }
9993
9994    public final void activitySlept(IBinder token) {
9995        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9996
9997        final long origId = Binder.clearCallingIdentity();
9998
9999        synchronized (this) {
10000            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10001            if (r != null) {
10002                mStackSupervisor.activitySleptLocked(r);
10003            }
10004        }
10005
10006        Binder.restoreCallingIdentity(origId);
10007    }
10008
10009    private String lockScreenShownToString() {
10010        switch (mLockScreenShown) {
10011            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10012            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10013            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10014            default: return "Unknown=" + mLockScreenShown;
10015        }
10016    }
10017
10018    void logLockScreen(String msg) {
10019        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10020                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10021                mWentToSleep + " mSleeping=" + mSleeping);
10022    }
10023
10024    void comeOutOfSleepIfNeededLocked() {
10025        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10026            if (mSleeping) {
10027                mSleeping = false;
10028                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10029            }
10030        }
10031    }
10032
10033    void wakingUp() {
10034        synchronized(this) {
10035            mWentToSleep = false;
10036            comeOutOfSleepIfNeededLocked();
10037        }
10038    }
10039
10040    void startRunningVoiceLocked() {
10041        if (!mRunningVoice) {
10042            mRunningVoice = true;
10043            comeOutOfSleepIfNeededLocked();
10044        }
10045    }
10046
10047    private void updateEventDispatchingLocked() {
10048        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10049    }
10050
10051    public void setLockScreenShown(boolean shown) {
10052        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10053                != PackageManager.PERMISSION_GRANTED) {
10054            throw new SecurityException("Requires permission "
10055                    + android.Manifest.permission.DEVICE_POWER);
10056        }
10057
10058        synchronized(this) {
10059            long ident = Binder.clearCallingIdentity();
10060            try {
10061                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10062                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10063                comeOutOfSleepIfNeededLocked();
10064            } finally {
10065                Binder.restoreCallingIdentity(ident);
10066            }
10067        }
10068    }
10069
10070    @Override
10071    public void stopAppSwitches() {
10072        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10073                != PackageManager.PERMISSION_GRANTED) {
10074            throw new SecurityException("Requires permission "
10075                    + android.Manifest.permission.STOP_APP_SWITCHES);
10076        }
10077
10078        synchronized(this) {
10079            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10080                    + APP_SWITCH_DELAY_TIME;
10081            mDidAppSwitch = false;
10082            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10083            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10084            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10085        }
10086    }
10087
10088    public void resumeAppSwitches() {
10089        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10090                != PackageManager.PERMISSION_GRANTED) {
10091            throw new SecurityException("Requires permission "
10092                    + android.Manifest.permission.STOP_APP_SWITCHES);
10093        }
10094
10095        synchronized(this) {
10096            // Note that we don't execute any pending app switches... we will
10097            // let those wait until either the timeout, or the next start
10098            // activity request.
10099            mAppSwitchesAllowedTime = 0;
10100        }
10101    }
10102
10103    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10104            int callingPid, int callingUid, String name) {
10105        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10106            return true;
10107        }
10108
10109        int perm = checkComponentPermission(
10110                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10111                sourceUid, -1, true);
10112        if (perm == PackageManager.PERMISSION_GRANTED) {
10113            return true;
10114        }
10115
10116        // If the actual IPC caller is different from the logical source, then
10117        // also see if they are allowed to control app switches.
10118        if (callingUid != -1 && callingUid != sourceUid) {
10119            perm = checkComponentPermission(
10120                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10121                    callingUid, -1, true);
10122            if (perm == PackageManager.PERMISSION_GRANTED) {
10123                return true;
10124            }
10125        }
10126
10127        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10128        return false;
10129    }
10130
10131    public void setDebugApp(String packageName, boolean waitForDebugger,
10132            boolean persistent) {
10133        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10134                "setDebugApp()");
10135
10136        long ident = Binder.clearCallingIdentity();
10137        try {
10138            // Note that this is not really thread safe if there are multiple
10139            // callers into it at the same time, but that's not a situation we
10140            // care about.
10141            if (persistent) {
10142                final ContentResolver resolver = mContext.getContentResolver();
10143                Settings.Global.putString(
10144                    resolver, Settings.Global.DEBUG_APP,
10145                    packageName);
10146                Settings.Global.putInt(
10147                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10148                    waitForDebugger ? 1 : 0);
10149            }
10150
10151            synchronized (this) {
10152                if (!persistent) {
10153                    mOrigDebugApp = mDebugApp;
10154                    mOrigWaitForDebugger = mWaitForDebugger;
10155                }
10156                mDebugApp = packageName;
10157                mWaitForDebugger = waitForDebugger;
10158                mDebugTransient = !persistent;
10159                if (packageName != null) {
10160                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10161                            false, UserHandle.USER_ALL, "set debug app");
10162                }
10163            }
10164        } finally {
10165            Binder.restoreCallingIdentity(ident);
10166        }
10167    }
10168
10169    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10170        synchronized (this) {
10171            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10172            if (!isDebuggable) {
10173                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10174                    throw new SecurityException("Process not debuggable: " + app.packageName);
10175                }
10176            }
10177
10178            mOpenGlTraceApp = processName;
10179        }
10180    }
10181
10182    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10183        synchronized (this) {
10184            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10185            if (!isDebuggable) {
10186                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10187                    throw new SecurityException("Process not debuggable: " + app.packageName);
10188                }
10189            }
10190            mProfileApp = processName;
10191            mProfileFile = profilerInfo.profileFile;
10192            if (mProfileFd != null) {
10193                try {
10194                    mProfileFd.close();
10195                } catch (IOException e) {
10196                }
10197                mProfileFd = null;
10198            }
10199            mProfileFd = profilerInfo.profileFd;
10200            mSamplingInterval = profilerInfo.samplingInterval;
10201            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10202            mProfileType = 0;
10203        }
10204    }
10205
10206    @Override
10207    public void setAlwaysFinish(boolean enabled) {
10208        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10209                "setAlwaysFinish()");
10210
10211        Settings.Global.putInt(
10212                mContext.getContentResolver(),
10213                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10214
10215        synchronized (this) {
10216            mAlwaysFinishActivities = enabled;
10217        }
10218    }
10219
10220    @Override
10221    public void setActivityController(IActivityController controller) {
10222        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10223                "setActivityController()");
10224        synchronized (this) {
10225            mController = controller;
10226            Watchdog.getInstance().setActivityController(controller);
10227        }
10228    }
10229
10230    @Override
10231    public void setUserIsMonkey(boolean userIsMonkey) {
10232        synchronized (this) {
10233            synchronized (mPidsSelfLocked) {
10234                final int callingPid = Binder.getCallingPid();
10235                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10236                if (precessRecord == null) {
10237                    throw new SecurityException("Unknown process: " + callingPid);
10238                }
10239                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10240                    throw new SecurityException("Only an instrumentation process "
10241                            + "with a UiAutomation can call setUserIsMonkey");
10242                }
10243            }
10244            mUserIsMonkey = userIsMonkey;
10245        }
10246    }
10247
10248    @Override
10249    public boolean isUserAMonkey() {
10250        synchronized (this) {
10251            // If there is a controller also implies the user is a monkey.
10252            return (mUserIsMonkey || mController != null);
10253        }
10254    }
10255
10256    public void requestBugReport() {
10257        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10258        SystemProperties.set("ctl.start", "bugreport");
10259    }
10260
10261    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10262        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10263    }
10264
10265    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10266        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10267            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10268        }
10269        return KEY_DISPATCHING_TIMEOUT;
10270    }
10271
10272    @Override
10273    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10274        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10275                != PackageManager.PERMISSION_GRANTED) {
10276            throw new SecurityException("Requires permission "
10277                    + android.Manifest.permission.FILTER_EVENTS);
10278        }
10279        ProcessRecord proc;
10280        long timeout;
10281        synchronized (this) {
10282            synchronized (mPidsSelfLocked) {
10283                proc = mPidsSelfLocked.get(pid);
10284            }
10285            timeout = getInputDispatchingTimeoutLocked(proc);
10286        }
10287
10288        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10289            return -1;
10290        }
10291
10292        return timeout;
10293    }
10294
10295    /**
10296     * Handle input dispatching timeouts.
10297     * Returns whether input dispatching should be aborted or not.
10298     */
10299    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10300            final ActivityRecord activity, final ActivityRecord parent,
10301            final boolean aboveSystem, String reason) {
10302        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10303                != PackageManager.PERMISSION_GRANTED) {
10304            throw new SecurityException("Requires permission "
10305                    + android.Manifest.permission.FILTER_EVENTS);
10306        }
10307
10308        final String annotation;
10309        if (reason == null) {
10310            annotation = "Input dispatching timed out";
10311        } else {
10312            annotation = "Input dispatching timed out (" + reason + ")";
10313        }
10314
10315        if (proc != null) {
10316            synchronized (this) {
10317                if (proc.debugging) {
10318                    return false;
10319                }
10320
10321                if (mDidDexOpt) {
10322                    // Give more time since we were dexopting.
10323                    mDidDexOpt = false;
10324                    return false;
10325                }
10326
10327                if (proc.instrumentationClass != null) {
10328                    Bundle info = new Bundle();
10329                    info.putString("shortMsg", "keyDispatchingTimedOut");
10330                    info.putString("longMsg", annotation);
10331                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10332                    return true;
10333                }
10334            }
10335            mHandler.post(new Runnable() {
10336                @Override
10337                public void run() {
10338                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10339                }
10340            });
10341        }
10342
10343        return true;
10344    }
10345
10346    public Bundle getAssistContextExtras(int requestType) {
10347        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10348                UserHandle.getCallingUserId());
10349        if (pae == null) {
10350            return null;
10351        }
10352        synchronized (pae) {
10353            while (!pae.haveResult) {
10354                try {
10355                    pae.wait();
10356                } catch (InterruptedException e) {
10357                }
10358            }
10359            if (pae.result != null) {
10360                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10361            }
10362        }
10363        synchronized (this) {
10364            mPendingAssistExtras.remove(pae);
10365            mHandler.removeCallbacks(pae);
10366        }
10367        return pae.extras;
10368    }
10369
10370    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10371            int userHandle) {
10372        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10373                "getAssistContextExtras()");
10374        PendingAssistExtras pae;
10375        Bundle extras = new Bundle();
10376        synchronized (this) {
10377            ActivityRecord activity = getFocusedStack().mResumedActivity;
10378            if (activity == null) {
10379                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10380                return null;
10381            }
10382            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10383            if (activity.app == null || activity.app.thread == null) {
10384                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10385                return null;
10386            }
10387            if (activity.app.pid == Binder.getCallingPid()) {
10388                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10389                return null;
10390            }
10391            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10392            try {
10393                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10394                        requestType);
10395                mPendingAssistExtras.add(pae);
10396                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10397            } catch (RemoteException e) {
10398                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10399                return null;
10400            }
10401            return pae;
10402        }
10403    }
10404
10405    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10406        PendingAssistExtras pae = (PendingAssistExtras)token;
10407        synchronized (pae) {
10408            pae.result = extras;
10409            pae.haveResult = true;
10410            pae.notifyAll();
10411            if (pae.intent == null) {
10412                // Caller is just waiting for the result.
10413                return;
10414            }
10415        }
10416
10417        // We are now ready to launch the assist activity.
10418        synchronized (this) {
10419            boolean exists = mPendingAssistExtras.remove(pae);
10420            mHandler.removeCallbacks(pae);
10421            if (!exists) {
10422                // Timed out.
10423                return;
10424            }
10425        }
10426        pae.intent.replaceExtras(extras);
10427        if (pae.hint != null) {
10428            pae.intent.putExtra(pae.hint, true);
10429        }
10430        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10431                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10432                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10433        closeSystemDialogs("assist");
10434        try {
10435            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10436        } catch (ActivityNotFoundException e) {
10437            Slog.w(TAG, "No activity to handle assist action.", e);
10438        }
10439    }
10440
10441    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10442        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10443    }
10444
10445    public void registerProcessObserver(IProcessObserver observer) {
10446        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10447                "registerProcessObserver()");
10448        synchronized (this) {
10449            mProcessObservers.register(observer);
10450        }
10451    }
10452
10453    @Override
10454    public void unregisterProcessObserver(IProcessObserver observer) {
10455        synchronized (this) {
10456            mProcessObservers.unregister(observer);
10457        }
10458    }
10459
10460    @Override
10461    public boolean convertFromTranslucent(IBinder token) {
10462        final long origId = Binder.clearCallingIdentity();
10463        try {
10464            synchronized (this) {
10465                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10466                if (r == null) {
10467                    return false;
10468                }
10469                final boolean translucentChanged = r.changeWindowTranslucency(true);
10470                if (translucentChanged) {
10471                    r.task.stack.releaseBackgroundResources();
10472                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10473                }
10474                mWindowManager.setAppFullscreen(token, true);
10475                return translucentChanged;
10476            }
10477        } finally {
10478            Binder.restoreCallingIdentity(origId);
10479        }
10480    }
10481
10482    @Override
10483    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10484        final long origId = Binder.clearCallingIdentity();
10485        try {
10486            synchronized (this) {
10487                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10488                if (r == null) {
10489                    return false;
10490                }
10491                int index = r.task.mActivities.lastIndexOf(r);
10492                if (index > 0) {
10493                    ActivityRecord under = r.task.mActivities.get(index - 1);
10494                    under.returningOptions = options;
10495                }
10496                final boolean translucentChanged = r.changeWindowTranslucency(false);
10497                if (translucentChanged) {
10498                    r.task.stack.convertToTranslucent(r);
10499                }
10500                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10501                mWindowManager.setAppFullscreen(token, false);
10502                return translucentChanged;
10503            }
10504        } finally {
10505            Binder.restoreCallingIdentity(origId);
10506        }
10507    }
10508
10509    @Override
10510    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10511        final long origId = Binder.clearCallingIdentity();
10512        try {
10513            synchronized (this) {
10514                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10515                if (r != null) {
10516                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10517                }
10518            }
10519            return false;
10520        } finally {
10521            Binder.restoreCallingIdentity(origId);
10522        }
10523    }
10524
10525    @Override
10526    public boolean isBackgroundVisibleBehind(IBinder token) {
10527        final long origId = Binder.clearCallingIdentity();
10528        try {
10529            synchronized (this) {
10530                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10531                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10532                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10533                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10534                return visible;
10535            }
10536        } finally {
10537            Binder.restoreCallingIdentity(origId);
10538        }
10539    }
10540
10541    @Override
10542    public ActivityOptions getActivityOptions(IBinder token) {
10543        final long origId = Binder.clearCallingIdentity();
10544        try {
10545            synchronized (this) {
10546                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10547                if (r != null) {
10548                    final ActivityOptions activityOptions = r.pendingOptions;
10549                    r.pendingOptions = null;
10550                    return activityOptions;
10551                }
10552                return null;
10553            }
10554        } finally {
10555            Binder.restoreCallingIdentity(origId);
10556        }
10557    }
10558
10559    @Override
10560    public void setImmersive(IBinder token, boolean immersive) {
10561        synchronized(this) {
10562            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10563            if (r == null) {
10564                throw new IllegalArgumentException();
10565            }
10566            r.immersive = immersive;
10567
10568            // update associated state if we're frontmost
10569            if (r == mFocusedActivity) {
10570                if (DEBUG_IMMERSIVE) {
10571                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10572                }
10573                applyUpdateLockStateLocked(r);
10574            }
10575        }
10576    }
10577
10578    @Override
10579    public boolean isImmersive(IBinder token) {
10580        synchronized (this) {
10581            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10582            if (r == null) {
10583                throw new IllegalArgumentException();
10584            }
10585            return r.immersive;
10586        }
10587    }
10588
10589    public boolean isTopActivityImmersive() {
10590        enforceNotIsolatedCaller("startActivity");
10591        synchronized (this) {
10592            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10593            return (r != null) ? r.immersive : false;
10594        }
10595    }
10596
10597    @Override
10598    public boolean isTopOfTask(IBinder token) {
10599        synchronized (this) {
10600            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10601            if (r == null) {
10602                throw new IllegalArgumentException();
10603            }
10604            return r.task.getTopActivity() == r;
10605        }
10606    }
10607
10608    public final void enterSafeMode() {
10609        synchronized(this) {
10610            // It only makes sense to do this before the system is ready
10611            // and started launching other packages.
10612            if (!mSystemReady) {
10613                try {
10614                    AppGlobals.getPackageManager().enterSafeMode();
10615                } catch (RemoteException e) {
10616                }
10617            }
10618
10619            mSafeMode = true;
10620        }
10621    }
10622
10623    public final void showSafeModeOverlay() {
10624        View v = LayoutInflater.from(mContext).inflate(
10625                com.android.internal.R.layout.safe_mode, null);
10626        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10627        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10628        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10629        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10630        lp.gravity = Gravity.BOTTOM | Gravity.START;
10631        lp.format = v.getBackground().getOpacity();
10632        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10633                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10634        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10635        ((WindowManager)mContext.getSystemService(
10636                Context.WINDOW_SERVICE)).addView(v, lp);
10637    }
10638
10639    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10640        if (!(sender instanceof PendingIntentRecord)) {
10641            return;
10642        }
10643        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10644        synchronized (stats) {
10645            if (mBatteryStatsService.isOnBattery()) {
10646                mBatteryStatsService.enforceCallingPermission();
10647                PendingIntentRecord rec = (PendingIntentRecord)sender;
10648                int MY_UID = Binder.getCallingUid();
10649                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10650                BatteryStatsImpl.Uid.Pkg pkg =
10651                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10652                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10653                pkg.incWakeupsLocked();
10654            }
10655        }
10656    }
10657
10658    public boolean killPids(int[] pids, String pReason, boolean secure) {
10659        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10660            throw new SecurityException("killPids only available to the system");
10661        }
10662        String reason = (pReason == null) ? "Unknown" : pReason;
10663        // XXX Note: don't acquire main activity lock here, because the window
10664        // manager calls in with its locks held.
10665
10666        boolean killed = false;
10667        synchronized (mPidsSelfLocked) {
10668            int[] types = new int[pids.length];
10669            int worstType = 0;
10670            for (int i=0; i<pids.length; i++) {
10671                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10672                if (proc != null) {
10673                    int type = proc.setAdj;
10674                    types[i] = type;
10675                    if (type > worstType) {
10676                        worstType = type;
10677                    }
10678                }
10679            }
10680
10681            // If the worst oom_adj is somewhere in the cached proc LRU range,
10682            // then constrain it so we will kill all cached procs.
10683            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10684                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10685                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10686            }
10687
10688            // If this is not a secure call, don't let it kill processes that
10689            // are important.
10690            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10691                worstType = ProcessList.SERVICE_ADJ;
10692            }
10693
10694            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10695            for (int i=0; i<pids.length; i++) {
10696                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10697                if (proc == null) {
10698                    continue;
10699                }
10700                int adj = proc.setAdj;
10701                if (adj >= worstType && !proc.killedByAm) {
10702                    proc.kill(reason, true);
10703                    killed = true;
10704                }
10705            }
10706        }
10707        return killed;
10708    }
10709
10710    @Override
10711    public void killUid(int uid, String reason) {
10712        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10713            throw new SecurityException("killUid only available to the system");
10714        }
10715        synchronized (this) {
10716            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10717                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10718                    reason != null ? reason : "kill uid");
10719        }
10720    }
10721
10722    @Override
10723    public boolean killProcessesBelowForeground(String reason) {
10724        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10725            throw new SecurityException("killProcessesBelowForeground() only available to system");
10726        }
10727
10728        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10729    }
10730
10731    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10732        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10733            throw new SecurityException("killProcessesBelowAdj() only available to system");
10734        }
10735
10736        boolean killed = false;
10737        synchronized (mPidsSelfLocked) {
10738            final int size = mPidsSelfLocked.size();
10739            for (int i = 0; i < size; i++) {
10740                final int pid = mPidsSelfLocked.keyAt(i);
10741                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10742                if (proc == null) continue;
10743
10744                final int adj = proc.setAdj;
10745                if (adj > belowAdj && !proc.killedByAm) {
10746                    proc.kill(reason, true);
10747                    killed = true;
10748                }
10749            }
10750        }
10751        return killed;
10752    }
10753
10754    @Override
10755    public void hang(final IBinder who, boolean allowRestart) {
10756        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10757                != PackageManager.PERMISSION_GRANTED) {
10758            throw new SecurityException("Requires permission "
10759                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10760        }
10761
10762        final IBinder.DeathRecipient death = new DeathRecipient() {
10763            @Override
10764            public void binderDied() {
10765                synchronized (this) {
10766                    notifyAll();
10767                }
10768            }
10769        };
10770
10771        try {
10772            who.linkToDeath(death, 0);
10773        } catch (RemoteException e) {
10774            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10775            return;
10776        }
10777
10778        synchronized (this) {
10779            Watchdog.getInstance().setAllowRestart(allowRestart);
10780            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10781            synchronized (death) {
10782                while (who.isBinderAlive()) {
10783                    try {
10784                        death.wait();
10785                    } catch (InterruptedException e) {
10786                    }
10787                }
10788            }
10789            Watchdog.getInstance().setAllowRestart(true);
10790        }
10791    }
10792
10793    @Override
10794    public void restart() {
10795        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10796                != PackageManager.PERMISSION_GRANTED) {
10797            throw new SecurityException("Requires permission "
10798                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10799        }
10800
10801        Log.i(TAG, "Sending shutdown broadcast...");
10802
10803        BroadcastReceiver br = new BroadcastReceiver() {
10804            @Override public void onReceive(Context context, Intent intent) {
10805                // Now the broadcast is done, finish up the low-level shutdown.
10806                Log.i(TAG, "Shutting down activity manager...");
10807                shutdown(10000);
10808                Log.i(TAG, "Shutdown complete, restarting!");
10809                Process.killProcess(Process.myPid());
10810                System.exit(10);
10811            }
10812        };
10813
10814        // First send the high-level shut down broadcast.
10815        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10816        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10817        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10818        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10819        mContext.sendOrderedBroadcastAsUser(intent,
10820                UserHandle.ALL, null, br, mHandler, 0, null, null);
10821        */
10822        br.onReceive(mContext, intent);
10823    }
10824
10825    private long getLowRamTimeSinceIdle(long now) {
10826        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10827    }
10828
10829    @Override
10830    public void performIdleMaintenance() {
10831        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10832                != PackageManager.PERMISSION_GRANTED) {
10833            throw new SecurityException("Requires permission "
10834                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10835        }
10836
10837        synchronized (this) {
10838            final long now = SystemClock.uptimeMillis();
10839            final long timeSinceLastIdle = now - mLastIdleTime;
10840            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10841            mLastIdleTime = now;
10842            mLowRamTimeSinceLastIdle = 0;
10843            if (mLowRamStartTime != 0) {
10844                mLowRamStartTime = now;
10845            }
10846
10847            StringBuilder sb = new StringBuilder(128);
10848            sb.append("Idle maintenance over ");
10849            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10850            sb.append(" low RAM for ");
10851            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10852            Slog.i(TAG, sb.toString());
10853
10854            // If at least 1/3 of our time since the last idle period has been spent
10855            // with RAM low, then we want to kill processes.
10856            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10857
10858            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10859                ProcessRecord proc = mLruProcesses.get(i);
10860                if (proc.notCachedSinceIdle) {
10861                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10862                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10863                        if (doKilling && proc.initialIdlePss != 0
10864                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10865                            proc.kill("idle maint (pss " + proc.lastPss
10866                                    + " from " + proc.initialIdlePss + ")", true);
10867                        }
10868                    }
10869                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10870                    proc.notCachedSinceIdle = true;
10871                    proc.initialIdlePss = 0;
10872                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10873                            isSleeping(), now);
10874                }
10875            }
10876
10877            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10878            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10879        }
10880    }
10881
10882    private void retrieveSettings() {
10883        final ContentResolver resolver = mContext.getContentResolver();
10884        String debugApp = Settings.Global.getString(
10885            resolver, Settings.Global.DEBUG_APP);
10886        boolean waitForDebugger = Settings.Global.getInt(
10887            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10888        boolean alwaysFinishActivities = Settings.Global.getInt(
10889            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10890        boolean forceRtl = Settings.Global.getInt(
10891                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10892        // Transfer any global setting for forcing RTL layout, into a System Property
10893        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10894
10895        Configuration configuration = new Configuration();
10896        Settings.System.getConfiguration(resolver, configuration);
10897        if (forceRtl) {
10898            // This will take care of setting the correct layout direction flags
10899            configuration.setLayoutDirection(configuration.locale);
10900        }
10901
10902        synchronized (this) {
10903            mDebugApp = mOrigDebugApp = debugApp;
10904            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10905            mAlwaysFinishActivities = alwaysFinishActivities;
10906            // This happens before any activities are started, so we can
10907            // change mConfiguration in-place.
10908            updateConfigurationLocked(configuration, null, false, true);
10909            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10910        }
10911    }
10912
10913    /** Loads resources after the current configuration has been set. */
10914    private void loadResourcesOnSystemReady() {
10915        final Resources res = mContext.getResources();
10916        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10917        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10918        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10919    }
10920
10921    public boolean testIsSystemReady() {
10922        // no need to synchronize(this) just to read & return the value
10923        return mSystemReady;
10924    }
10925
10926    private static File getCalledPreBootReceiversFile() {
10927        File dataDir = Environment.getDataDirectory();
10928        File systemDir = new File(dataDir, "system");
10929        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10930        return fname;
10931    }
10932
10933    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10934        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10935        File file = getCalledPreBootReceiversFile();
10936        FileInputStream fis = null;
10937        try {
10938            fis = new FileInputStream(file);
10939            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10940            int fvers = dis.readInt();
10941            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10942                String vers = dis.readUTF();
10943                String codename = dis.readUTF();
10944                String build = dis.readUTF();
10945                if (android.os.Build.VERSION.RELEASE.equals(vers)
10946                        && android.os.Build.VERSION.CODENAME.equals(codename)
10947                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10948                    int num = dis.readInt();
10949                    while (num > 0) {
10950                        num--;
10951                        String pkg = dis.readUTF();
10952                        String cls = dis.readUTF();
10953                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10954                    }
10955                }
10956            }
10957        } catch (FileNotFoundException e) {
10958        } catch (IOException e) {
10959            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10960        } finally {
10961            if (fis != null) {
10962                try {
10963                    fis.close();
10964                } catch (IOException e) {
10965                }
10966            }
10967        }
10968        return lastDoneReceivers;
10969    }
10970
10971    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10972        File file = getCalledPreBootReceiversFile();
10973        FileOutputStream fos = null;
10974        DataOutputStream dos = null;
10975        try {
10976            fos = new FileOutputStream(file);
10977            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10978            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10979            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10980            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10981            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10982            dos.writeInt(list.size());
10983            for (int i=0; i<list.size(); i++) {
10984                dos.writeUTF(list.get(i).getPackageName());
10985                dos.writeUTF(list.get(i).getClassName());
10986            }
10987        } catch (IOException e) {
10988            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10989            file.delete();
10990        } finally {
10991            FileUtils.sync(fos);
10992            if (dos != null) {
10993                try {
10994                    dos.close();
10995                } catch (IOException e) {
10996                    // TODO Auto-generated catch block
10997                    e.printStackTrace();
10998                }
10999            }
11000        }
11001    }
11002
11003    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11004            ArrayList<ComponentName> doneReceivers, int userId) {
11005        boolean waitingUpdate = false;
11006        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11007        List<ResolveInfo> ris = null;
11008        try {
11009            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11010                    intent, null, 0, userId);
11011        } catch (RemoteException e) {
11012        }
11013        if (ris != null) {
11014            for (int i=ris.size()-1; i>=0; i--) {
11015                if ((ris.get(i).activityInfo.applicationInfo.flags
11016                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11017                    ris.remove(i);
11018                }
11019            }
11020            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11021
11022            // For User 0, load the version number. When delivering to a new user, deliver
11023            // to all receivers.
11024            if (userId == UserHandle.USER_OWNER) {
11025                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11026                for (int i=0; i<ris.size(); i++) {
11027                    ActivityInfo ai = ris.get(i).activityInfo;
11028                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11029                    if (lastDoneReceivers.contains(comp)) {
11030                        // We already did the pre boot receiver for this app with the current
11031                        // platform version, so don't do it again...
11032                        ris.remove(i);
11033                        i--;
11034                        // ...however, do keep it as one that has been done, so we don't
11035                        // forget about it when rewriting the file of last done receivers.
11036                        doneReceivers.add(comp);
11037                    }
11038                }
11039            }
11040
11041            // If primary user, send broadcast to all available users, else just to userId
11042            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11043                    : new int[] { userId };
11044            for (int i = 0; i < ris.size(); i++) {
11045                ActivityInfo ai = ris.get(i).activityInfo;
11046                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11047                doneReceivers.add(comp);
11048                intent.setComponent(comp);
11049                for (int j=0; j<users.length; j++) {
11050                    IIntentReceiver finisher = null;
11051                    // On last receiver and user, set up a completion callback
11052                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11053                        finisher = new IIntentReceiver.Stub() {
11054                            public void performReceive(Intent intent, int resultCode,
11055                                    String data, Bundle extras, boolean ordered,
11056                                    boolean sticky, int sendingUser) {
11057                                // The raw IIntentReceiver interface is called
11058                                // with the AM lock held, so redispatch to
11059                                // execute our code without the lock.
11060                                mHandler.post(onFinishCallback);
11061                            }
11062                        };
11063                    }
11064                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11065                            + " for user " + users[j]);
11066                    broadcastIntentLocked(null, null, intent, null, finisher,
11067                            0, null, null, null, AppOpsManager.OP_NONE,
11068                            true, false, MY_PID, Process.SYSTEM_UID,
11069                            users[j]);
11070                    if (finisher != null) {
11071                        waitingUpdate = true;
11072                    }
11073                }
11074            }
11075        }
11076
11077        return waitingUpdate;
11078    }
11079
11080    public void systemReady(final Runnable goingCallback) {
11081        synchronized(this) {
11082            if (mSystemReady) {
11083                // If we're done calling all the receivers, run the next "boot phase" passed in
11084                // by the SystemServer
11085                if (goingCallback != null) {
11086                    goingCallback.run();
11087                }
11088                return;
11089            }
11090
11091            // Make sure we have the current profile info, since it is needed for
11092            // security checks.
11093            updateCurrentProfileIdsLocked();
11094
11095            if (mRecentTasks == null) {
11096                mRecentTasks = mTaskPersister.restoreTasksLocked();
11097                if (!mRecentTasks.isEmpty()) {
11098                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11099                }
11100                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11101                mTaskPersister.startPersisting();
11102            }
11103
11104            // Check to see if there are any update receivers to run.
11105            if (!mDidUpdate) {
11106                if (mWaitingUpdate) {
11107                    return;
11108                }
11109                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11110                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11111                    public void run() {
11112                        synchronized (ActivityManagerService.this) {
11113                            mDidUpdate = true;
11114                        }
11115                        writeLastDonePreBootReceivers(doneReceivers);
11116                        showBootMessage(mContext.getText(
11117                                R.string.android_upgrading_complete),
11118                                false);
11119                        systemReady(goingCallback);
11120                    }
11121                }, doneReceivers, UserHandle.USER_OWNER);
11122
11123                if (mWaitingUpdate) {
11124                    return;
11125                }
11126                mDidUpdate = true;
11127            }
11128
11129            mAppOpsService.systemReady();
11130            mSystemReady = true;
11131        }
11132
11133        ArrayList<ProcessRecord> procsToKill = null;
11134        synchronized(mPidsSelfLocked) {
11135            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11136                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11137                if (!isAllowedWhileBooting(proc.info)){
11138                    if (procsToKill == null) {
11139                        procsToKill = new ArrayList<ProcessRecord>();
11140                    }
11141                    procsToKill.add(proc);
11142                }
11143            }
11144        }
11145
11146        synchronized(this) {
11147            if (procsToKill != null) {
11148                for (int i=procsToKill.size()-1; i>=0; i--) {
11149                    ProcessRecord proc = procsToKill.get(i);
11150                    Slog.i(TAG, "Removing system update proc: " + proc);
11151                    removeProcessLocked(proc, true, false, "system update done");
11152                }
11153            }
11154
11155            // Now that we have cleaned up any update processes, we
11156            // are ready to start launching real processes and know that
11157            // we won't trample on them any more.
11158            mProcessesReady = true;
11159        }
11160
11161        Slog.i(TAG, "System now ready");
11162        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11163            SystemClock.uptimeMillis());
11164
11165        synchronized(this) {
11166            // Make sure we have no pre-ready processes sitting around.
11167
11168            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11169                ResolveInfo ri = mContext.getPackageManager()
11170                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11171                                STOCK_PM_FLAGS);
11172                CharSequence errorMsg = null;
11173                if (ri != null) {
11174                    ActivityInfo ai = ri.activityInfo;
11175                    ApplicationInfo app = ai.applicationInfo;
11176                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11177                        mTopAction = Intent.ACTION_FACTORY_TEST;
11178                        mTopData = null;
11179                        mTopComponent = new ComponentName(app.packageName,
11180                                ai.name);
11181                    } else {
11182                        errorMsg = mContext.getResources().getText(
11183                                com.android.internal.R.string.factorytest_not_system);
11184                    }
11185                } else {
11186                    errorMsg = mContext.getResources().getText(
11187                            com.android.internal.R.string.factorytest_no_action);
11188                }
11189                if (errorMsg != null) {
11190                    mTopAction = null;
11191                    mTopData = null;
11192                    mTopComponent = null;
11193                    Message msg = Message.obtain();
11194                    msg.what = SHOW_FACTORY_ERROR_MSG;
11195                    msg.getData().putCharSequence("msg", errorMsg);
11196                    mHandler.sendMessage(msg);
11197                }
11198            }
11199        }
11200
11201        retrieveSettings();
11202        loadResourcesOnSystemReady();
11203
11204        synchronized (this) {
11205            readGrantedUriPermissionsLocked();
11206        }
11207
11208        if (goingCallback != null) goingCallback.run();
11209
11210        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11211                Integer.toString(mCurrentUserId), mCurrentUserId);
11212        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11213                Integer.toString(mCurrentUserId), mCurrentUserId);
11214        mSystemServiceManager.startUser(mCurrentUserId);
11215
11216        synchronized (this) {
11217            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11218                try {
11219                    List apps = AppGlobals.getPackageManager().
11220                        getPersistentApplications(STOCK_PM_FLAGS);
11221                    if (apps != null) {
11222                        int N = apps.size();
11223                        int i;
11224                        for (i=0; i<N; i++) {
11225                            ApplicationInfo info
11226                                = (ApplicationInfo)apps.get(i);
11227                            if (info != null &&
11228                                    !info.packageName.equals("android")) {
11229                                addAppLocked(info, false, null /* ABI override */);
11230                            }
11231                        }
11232                    }
11233                } catch (RemoteException ex) {
11234                    // pm is in same process, this will never happen.
11235                }
11236            }
11237
11238            // Start up initial activity.
11239            mBooting = true;
11240            startHomeActivityLocked(mCurrentUserId);
11241
11242            try {
11243                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11244                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11245                            + " data partition or your device will be unstable.");
11246                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11247                }
11248            } catch (RemoteException e) {
11249            }
11250
11251            if (!Build.isFingerprintConsistent()) {
11252                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11253                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11254            }
11255
11256            long ident = Binder.clearCallingIdentity();
11257            try {
11258                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11259                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11260                        | Intent.FLAG_RECEIVER_FOREGROUND);
11261                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11262                broadcastIntentLocked(null, null, intent,
11263                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11264                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11265                intent = new Intent(Intent.ACTION_USER_STARTING);
11266                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11267                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11268                broadcastIntentLocked(null, null, intent,
11269                        null, new IIntentReceiver.Stub() {
11270                            @Override
11271                            public void performReceive(Intent intent, int resultCode, String data,
11272                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11273                                    throws RemoteException {
11274                            }
11275                        }, 0, null, null,
11276                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11277                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11278            } catch (Throwable t) {
11279                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11280            } finally {
11281                Binder.restoreCallingIdentity(ident);
11282            }
11283            mStackSupervisor.resumeTopActivitiesLocked();
11284            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11285        }
11286    }
11287
11288    private boolean makeAppCrashingLocked(ProcessRecord app,
11289            String shortMsg, String longMsg, String stackTrace) {
11290        app.crashing = true;
11291        app.crashingReport = generateProcessError(app,
11292                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11293        startAppProblemLocked(app);
11294        app.stopFreezingAllLocked();
11295        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11296    }
11297
11298    private void makeAppNotRespondingLocked(ProcessRecord app,
11299            String activity, String shortMsg, String longMsg) {
11300        app.notResponding = true;
11301        app.notRespondingReport = generateProcessError(app,
11302                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11303                activity, shortMsg, longMsg, null);
11304        startAppProblemLocked(app);
11305        app.stopFreezingAllLocked();
11306    }
11307
11308    /**
11309     * Generate a process error record, suitable for attachment to a ProcessRecord.
11310     *
11311     * @param app The ProcessRecord in which the error occurred.
11312     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11313     *                      ActivityManager.AppErrorStateInfo
11314     * @param activity The activity associated with the crash, if known.
11315     * @param shortMsg Short message describing the crash.
11316     * @param longMsg Long message describing the crash.
11317     * @param stackTrace Full crash stack trace, may be null.
11318     *
11319     * @return Returns a fully-formed AppErrorStateInfo record.
11320     */
11321    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11322            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11323        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11324
11325        report.condition = condition;
11326        report.processName = app.processName;
11327        report.pid = app.pid;
11328        report.uid = app.info.uid;
11329        report.tag = activity;
11330        report.shortMsg = shortMsg;
11331        report.longMsg = longMsg;
11332        report.stackTrace = stackTrace;
11333
11334        return report;
11335    }
11336
11337    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11338        synchronized (this) {
11339            app.crashing = false;
11340            app.crashingReport = null;
11341            app.notResponding = false;
11342            app.notRespondingReport = null;
11343            if (app.anrDialog == fromDialog) {
11344                app.anrDialog = null;
11345            }
11346            if (app.waitDialog == fromDialog) {
11347                app.waitDialog = null;
11348            }
11349            if (app.pid > 0 && app.pid != MY_PID) {
11350                handleAppCrashLocked(app, null, null, null);
11351                app.kill("user request after error", true);
11352            }
11353        }
11354    }
11355
11356    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11357            String stackTrace) {
11358        long now = SystemClock.uptimeMillis();
11359
11360        Long crashTime;
11361        if (!app.isolated) {
11362            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11363        } else {
11364            crashTime = null;
11365        }
11366        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11367            // This process loses!
11368            Slog.w(TAG, "Process " + app.info.processName
11369                    + " has crashed too many times: killing!");
11370            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11371                    app.userId, app.info.processName, app.uid);
11372            mStackSupervisor.handleAppCrashLocked(app);
11373            if (!app.persistent) {
11374                // We don't want to start this process again until the user
11375                // explicitly does so...  but for persistent process, we really
11376                // need to keep it running.  If a persistent process is actually
11377                // repeatedly crashing, then badness for everyone.
11378                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11379                        app.info.processName);
11380                if (!app.isolated) {
11381                    // XXX We don't have a way to mark isolated processes
11382                    // as bad, since they don't have a peristent identity.
11383                    mBadProcesses.put(app.info.processName, app.uid,
11384                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11385                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11386                }
11387                app.bad = true;
11388                app.removed = true;
11389                // Don't let services in this process be restarted and potentially
11390                // annoy the user repeatedly.  Unless it is persistent, since those
11391                // processes run critical code.
11392                removeProcessLocked(app, false, false, "crash");
11393                mStackSupervisor.resumeTopActivitiesLocked();
11394                return false;
11395            }
11396            mStackSupervisor.resumeTopActivitiesLocked();
11397        } else {
11398            mStackSupervisor.finishTopRunningActivityLocked(app);
11399        }
11400
11401        // Bump up the crash count of any services currently running in the proc.
11402        for (int i=app.services.size()-1; i>=0; i--) {
11403            // Any services running in the application need to be placed
11404            // back in the pending list.
11405            ServiceRecord sr = app.services.valueAt(i);
11406            sr.crashCount++;
11407        }
11408
11409        // If the crashing process is what we consider to be the "home process" and it has been
11410        // replaced by a third-party app, clear the package preferred activities from packages
11411        // with a home activity running in the process to prevent a repeatedly crashing app
11412        // from blocking the user to manually clear the list.
11413        final ArrayList<ActivityRecord> activities = app.activities;
11414        if (app == mHomeProcess && activities.size() > 0
11415                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11416            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11417                final ActivityRecord r = activities.get(activityNdx);
11418                if (r.isHomeActivity()) {
11419                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11420                    try {
11421                        ActivityThread.getPackageManager()
11422                                .clearPackagePreferredActivities(r.packageName);
11423                    } catch (RemoteException c) {
11424                        // pm is in same process, this will never happen.
11425                    }
11426                }
11427            }
11428        }
11429
11430        if (!app.isolated) {
11431            // XXX Can't keep track of crash times for isolated processes,
11432            // because they don't have a perisistent identity.
11433            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11434        }
11435
11436        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11437        return true;
11438    }
11439
11440    void startAppProblemLocked(ProcessRecord app) {
11441        // If this app is not running under the current user, then we
11442        // can't give it a report button because that would require
11443        // launching the report UI under a different user.
11444        app.errorReportReceiver = null;
11445
11446        for (int userId : mCurrentProfileIds) {
11447            if (app.userId == userId) {
11448                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11449                        mContext, app.info.packageName, app.info.flags);
11450            }
11451        }
11452        skipCurrentReceiverLocked(app);
11453    }
11454
11455    void skipCurrentReceiverLocked(ProcessRecord app) {
11456        for (BroadcastQueue queue : mBroadcastQueues) {
11457            queue.skipCurrentReceiverLocked(app);
11458        }
11459    }
11460
11461    /**
11462     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11463     * The application process will exit immediately after this call returns.
11464     * @param app object of the crashing app, null for the system server
11465     * @param crashInfo describing the exception
11466     */
11467    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11468        ProcessRecord r = findAppProcess(app, "Crash");
11469        final String processName = app == null ? "system_server"
11470                : (r == null ? "unknown" : r.processName);
11471
11472        handleApplicationCrashInner("crash", r, processName, crashInfo);
11473    }
11474
11475    /* Native crash reporting uses this inner version because it needs to be somewhat
11476     * decoupled from the AM-managed cleanup lifecycle
11477     */
11478    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11479            ApplicationErrorReport.CrashInfo crashInfo) {
11480        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11481                UserHandle.getUserId(Binder.getCallingUid()), processName,
11482                r == null ? -1 : r.info.flags,
11483                crashInfo.exceptionClassName,
11484                crashInfo.exceptionMessage,
11485                crashInfo.throwFileName,
11486                crashInfo.throwLineNumber);
11487
11488        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11489
11490        crashApplication(r, crashInfo);
11491    }
11492
11493    public void handleApplicationStrictModeViolation(
11494            IBinder app,
11495            int violationMask,
11496            StrictMode.ViolationInfo info) {
11497        ProcessRecord r = findAppProcess(app, "StrictMode");
11498        if (r == null) {
11499            return;
11500        }
11501
11502        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11503            Integer stackFingerprint = info.hashCode();
11504            boolean logIt = true;
11505            synchronized (mAlreadyLoggedViolatedStacks) {
11506                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11507                    logIt = false;
11508                    // TODO: sub-sample into EventLog for these, with
11509                    // the info.durationMillis?  Then we'd get
11510                    // the relative pain numbers, without logging all
11511                    // the stack traces repeatedly.  We'd want to do
11512                    // likewise in the client code, which also does
11513                    // dup suppression, before the Binder call.
11514                } else {
11515                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11516                        mAlreadyLoggedViolatedStacks.clear();
11517                    }
11518                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11519                }
11520            }
11521            if (logIt) {
11522                logStrictModeViolationToDropBox(r, info);
11523            }
11524        }
11525
11526        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11527            AppErrorResult result = new AppErrorResult();
11528            synchronized (this) {
11529                final long origId = Binder.clearCallingIdentity();
11530
11531                Message msg = Message.obtain();
11532                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11533                HashMap<String, Object> data = new HashMap<String, Object>();
11534                data.put("result", result);
11535                data.put("app", r);
11536                data.put("violationMask", violationMask);
11537                data.put("info", info);
11538                msg.obj = data;
11539                mHandler.sendMessage(msg);
11540
11541                Binder.restoreCallingIdentity(origId);
11542            }
11543            int res = result.get();
11544            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11545        }
11546    }
11547
11548    // Depending on the policy in effect, there could be a bunch of
11549    // these in quick succession so we try to batch these together to
11550    // minimize disk writes, number of dropbox entries, and maximize
11551    // compression, by having more fewer, larger records.
11552    private void logStrictModeViolationToDropBox(
11553            ProcessRecord process,
11554            StrictMode.ViolationInfo info) {
11555        if (info == null) {
11556            return;
11557        }
11558        final boolean isSystemApp = process == null ||
11559                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11560                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11561        final String processName = process == null ? "unknown" : process.processName;
11562        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11563        final DropBoxManager dbox = (DropBoxManager)
11564                mContext.getSystemService(Context.DROPBOX_SERVICE);
11565
11566        // Exit early if the dropbox isn't configured to accept this report type.
11567        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11568
11569        boolean bufferWasEmpty;
11570        boolean needsFlush;
11571        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11572        synchronized (sb) {
11573            bufferWasEmpty = sb.length() == 0;
11574            appendDropBoxProcessHeaders(process, processName, sb);
11575            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11576            sb.append("System-App: ").append(isSystemApp).append("\n");
11577            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11578            if (info.violationNumThisLoop != 0) {
11579                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11580            }
11581            if (info.numAnimationsRunning != 0) {
11582                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11583            }
11584            if (info.broadcastIntentAction != null) {
11585                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11586            }
11587            if (info.durationMillis != -1) {
11588                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11589            }
11590            if (info.numInstances != -1) {
11591                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11592            }
11593            if (info.tags != null) {
11594                for (String tag : info.tags) {
11595                    sb.append("Span-Tag: ").append(tag).append("\n");
11596                }
11597            }
11598            sb.append("\n");
11599            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11600                sb.append(info.crashInfo.stackTrace);
11601            }
11602            sb.append("\n");
11603
11604            // Only buffer up to ~64k.  Various logging bits truncate
11605            // things at 128k.
11606            needsFlush = (sb.length() > 64 * 1024);
11607        }
11608
11609        // Flush immediately if the buffer's grown too large, or this
11610        // is a non-system app.  Non-system apps are isolated with a
11611        // different tag & policy and not batched.
11612        //
11613        // Batching is useful during internal testing with
11614        // StrictMode settings turned up high.  Without batching,
11615        // thousands of separate files could be created on boot.
11616        if (!isSystemApp || needsFlush) {
11617            new Thread("Error dump: " + dropboxTag) {
11618                @Override
11619                public void run() {
11620                    String report;
11621                    synchronized (sb) {
11622                        report = sb.toString();
11623                        sb.delete(0, sb.length());
11624                        sb.trimToSize();
11625                    }
11626                    if (report.length() != 0) {
11627                        dbox.addText(dropboxTag, report);
11628                    }
11629                }
11630            }.start();
11631            return;
11632        }
11633
11634        // System app batching:
11635        if (!bufferWasEmpty) {
11636            // An existing dropbox-writing thread is outstanding, so
11637            // we don't need to start it up.  The existing thread will
11638            // catch the buffer appends we just did.
11639            return;
11640        }
11641
11642        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11643        // (After this point, we shouldn't access AMS internal data structures.)
11644        new Thread("Error dump: " + dropboxTag) {
11645            @Override
11646            public void run() {
11647                // 5 second sleep to let stacks arrive and be batched together
11648                try {
11649                    Thread.sleep(5000);  // 5 seconds
11650                } catch (InterruptedException e) {}
11651
11652                String errorReport;
11653                synchronized (mStrictModeBuffer) {
11654                    errorReport = mStrictModeBuffer.toString();
11655                    if (errorReport.length() == 0) {
11656                        return;
11657                    }
11658                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11659                    mStrictModeBuffer.trimToSize();
11660                }
11661                dbox.addText(dropboxTag, errorReport);
11662            }
11663        }.start();
11664    }
11665
11666    /**
11667     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11668     * @param app object of the crashing app, null for the system server
11669     * @param tag reported by the caller
11670     * @param system whether this wtf is coming from the system
11671     * @param crashInfo describing the context of the error
11672     * @return true if the process should exit immediately (WTF is fatal)
11673     */
11674    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11675            final ApplicationErrorReport.CrashInfo crashInfo) {
11676        final int callingUid = Binder.getCallingUid();
11677        final int callingPid = Binder.getCallingPid();
11678
11679        if (system) {
11680            // If this is coming from the system, we could very well have low-level
11681            // system locks held, so we want to do this all asynchronously.  And we
11682            // never want this to become fatal, so there is that too.
11683            mHandler.post(new Runnable() {
11684                @Override public void run() {
11685                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11686                }
11687            });
11688            return false;
11689        }
11690
11691        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11692                crashInfo);
11693
11694        if (r != null && r.pid != Process.myPid() &&
11695                Settings.Global.getInt(mContext.getContentResolver(),
11696                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11697            crashApplication(r, crashInfo);
11698            return true;
11699        } else {
11700            return false;
11701        }
11702    }
11703
11704    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11705            final ApplicationErrorReport.CrashInfo crashInfo) {
11706        final ProcessRecord r = findAppProcess(app, "WTF");
11707        final String processName = app == null ? "system_server"
11708                : (r == null ? "unknown" : r.processName);
11709
11710        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11711                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11712
11713        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11714
11715        return r;
11716    }
11717
11718    /**
11719     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11720     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11721     */
11722    private ProcessRecord findAppProcess(IBinder app, String reason) {
11723        if (app == null) {
11724            return null;
11725        }
11726
11727        synchronized (this) {
11728            final int NP = mProcessNames.getMap().size();
11729            for (int ip=0; ip<NP; ip++) {
11730                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11731                final int NA = apps.size();
11732                for (int ia=0; ia<NA; ia++) {
11733                    ProcessRecord p = apps.valueAt(ia);
11734                    if (p.thread != null && p.thread.asBinder() == app) {
11735                        return p;
11736                    }
11737                }
11738            }
11739
11740            Slog.w(TAG, "Can't find mystery application for " + reason
11741                    + " from pid=" + Binder.getCallingPid()
11742                    + " uid=" + Binder.getCallingUid() + ": " + app);
11743            return null;
11744        }
11745    }
11746
11747    /**
11748     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11749     * to append various headers to the dropbox log text.
11750     */
11751    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11752            StringBuilder sb) {
11753        // Watchdog thread ends up invoking this function (with
11754        // a null ProcessRecord) to add the stack file to dropbox.
11755        // Do not acquire a lock on this (am) in such cases, as it
11756        // could cause a potential deadlock, if and when watchdog
11757        // is invoked due to unavailability of lock on am and it
11758        // would prevent watchdog from killing system_server.
11759        if (process == null) {
11760            sb.append("Process: ").append(processName).append("\n");
11761            return;
11762        }
11763        // Note: ProcessRecord 'process' is guarded by the service
11764        // instance.  (notably process.pkgList, which could otherwise change
11765        // concurrently during execution of this method)
11766        synchronized (this) {
11767            sb.append("Process: ").append(processName).append("\n");
11768            int flags = process.info.flags;
11769            IPackageManager pm = AppGlobals.getPackageManager();
11770            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11771            for (int ip=0; ip<process.pkgList.size(); ip++) {
11772                String pkg = process.pkgList.keyAt(ip);
11773                sb.append("Package: ").append(pkg);
11774                try {
11775                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11776                    if (pi != null) {
11777                        sb.append(" v").append(pi.versionCode);
11778                        if (pi.versionName != null) {
11779                            sb.append(" (").append(pi.versionName).append(")");
11780                        }
11781                    }
11782                } catch (RemoteException e) {
11783                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11784                }
11785                sb.append("\n");
11786            }
11787        }
11788    }
11789
11790    private static String processClass(ProcessRecord process) {
11791        if (process == null || process.pid == MY_PID) {
11792            return "system_server";
11793        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11794            return "system_app";
11795        } else {
11796            return "data_app";
11797        }
11798    }
11799
11800    /**
11801     * Write a description of an error (crash, WTF, ANR) to the drop box.
11802     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11803     * @param process which caused the error, null means the system server
11804     * @param activity which triggered the error, null if unknown
11805     * @param parent activity related to the error, null if unknown
11806     * @param subject line related to the error, null if absent
11807     * @param report in long form describing the error, null if absent
11808     * @param logFile to include in the report, null if none
11809     * @param crashInfo giving an application stack trace, null if absent
11810     */
11811    public void addErrorToDropBox(String eventType,
11812            ProcessRecord process, String processName, ActivityRecord activity,
11813            ActivityRecord parent, String subject,
11814            final String report, final File logFile,
11815            final ApplicationErrorReport.CrashInfo crashInfo) {
11816        // NOTE -- this must never acquire the ActivityManagerService lock,
11817        // otherwise the watchdog may be prevented from resetting the system.
11818
11819        final String dropboxTag = processClass(process) + "_" + eventType;
11820        final DropBoxManager dbox = (DropBoxManager)
11821                mContext.getSystemService(Context.DROPBOX_SERVICE);
11822
11823        // Exit early if the dropbox isn't configured to accept this report type.
11824        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11825
11826        final StringBuilder sb = new StringBuilder(1024);
11827        appendDropBoxProcessHeaders(process, processName, sb);
11828        if (activity != null) {
11829            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11830        }
11831        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11832            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11833        }
11834        if (parent != null && parent != activity) {
11835            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11836        }
11837        if (subject != null) {
11838            sb.append("Subject: ").append(subject).append("\n");
11839        }
11840        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11841        if (Debug.isDebuggerConnected()) {
11842            sb.append("Debugger: Connected\n");
11843        }
11844        sb.append("\n");
11845
11846        // Do the rest in a worker thread to avoid blocking the caller on I/O
11847        // (After this point, we shouldn't access AMS internal data structures.)
11848        Thread worker = new Thread("Error dump: " + dropboxTag) {
11849            @Override
11850            public void run() {
11851                if (report != null) {
11852                    sb.append(report);
11853                }
11854                if (logFile != null) {
11855                    try {
11856                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11857                                    "\n\n[[TRUNCATED]]"));
11858                    } catch (IOException e) {
11859                        Slog.e(TAG, "Error reading " + logFile, e);
11860                    }
11861                }
11862                if (crashInfo != null && crashInfo.stackTrace != null) {
11863                    sb.append(crashInfo.stackTrace);
11864                }
11865
11866                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11867                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11868                if (lines > 0) {
11869                    sb.append("\n");
11870
11871                    // Merge several logcat streams, and take the last N lines
11872                    InputStreamReader input = null;
11873                    try {
11874                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11875                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11876                                "-b", "crash",
11877                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11878
11879                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11880                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11881                        input = new InputStreamReader(logcat.getInputStream());
11882
11883                        int num;
11884                        char[] buf = new char[8192];
11885                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11886                    } catch (IOException e) {
11887                        Slog.e(TAG, "Error running logcat", e);
11888                    } finally {
11889                        if (input != null) try { input.close(); } catch (IOException e) {}
11890                    }
11891                }
11892
11893                dbox.addText(dropboxTag, sb.toString());
11894            }
11895        };
11896
11897        if (process == null) {
11898            // If process is null, we are being called from some internal code
11899            // and may be about to die -- run this synchronously.
11900            worker.run();
11901        } else {
11902            worker.start();
11903        }
11904    }
11905
11906    /**
11907     * Bring up the "unexpected error" dialog box for a crashing app.
11908     * Deal with edge cases (intercepts from instrumented applications,
11909     * ActivityController, error intent receivers, that sort of thing).
11910     * @param r the application crashing
11911     * @param crashInfo describing the failure
11912     */
11913    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11914        long timeMillis = System.currentTimeMillis();
11915        String shortMsg = crashInfo.exceptionClassName;
11916        String longMsg = crashInfo.exceptionMessage;
11917        String stackTrace = crashInfo.stackTrace;
11918        if (shortMsg != null && longMsg != null) {
11919            longMsg = shortMsg + ": " + longMsg;
11920        } else if (shortMsg != null) {
11921            longMsg = shortMsg;
11922        }
11923
11924        AppErrorResult result = new AppErrorResult();
11925        synchronized (this) {
11926            if (mController != null) {
11927                try {
11928                    String name = r != null ? r.processName : null;
11929                    int pid = r != null ? r.pid : Binder.getCallingPid();
11930                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11931                    if (!mController.appCrashed(name, pid,
11932                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11933                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11934                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11935                            Slog.w(TAG, "Skip killing native crashed app " + name
11936                                    + "(" + pid + ") during testing");
11937                        } else {
11938                            Slog.w(TAG, "Force-killing crashed app " + name
11939                                    + " at watcher's request");
11940                            if (r != null) {
11941                                r.kill("crash", true);
11942                            } else {
11943                                // Huh.
11944                                Process.killProcess(pid);
11945                                Process.killProcessGroup(uid, pid);
11946                            }
11947                        }
11948                        return;
11949                    }
11950                } catch (RemoteException e) {
11951                    mController = null;
11952                    Watchdog.getInstance().setActivityController(null);
11953                }
11954            }
11955
11956            final long origId = Binder.clearCallingIdentity();
11957
11958            // If this process is running instrumentation, finish it.
11959            if (r != null && r.instrumentationClass != null) {
11960                Slog.w(TAG, "Error in app " + r.processName
11961                      + " running instrumentation " + r.instrumentationClass + ":");
11962                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11963                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11964                Bundle info = new Bundle();
11965                info.putString("shortMsg", shortMsg);
11966                info.putString("longMsg", longMsg);
11967                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11968                Binder.restoreCallingIdentity(origId);
11969                return;
11970            }
11971
11972            // If we can't identify the process or it's already exceeded its crash quota,
11973            // quit right away without showing a crash dialog.
11974            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11975                Binder.restoreCallingIdentity(origId);
11976                return;
11977            }
11978
11979            Message msg = Message.obtain();
11980            msg.what = SHOW_ERROR_MSG;
11981            HashMap data = new HashMap();
11982            data.put("result", result);
11983            data.put("app", r);
11984            msg.obj = data;
11985            mHandler.sendMessage(msg);
11986
11987            Binder.restoreCallingIdentity(origId);
11988        }
11989
11990        int res = result.get();
11991
11992        Intent appErrorIntent = null;
11993        synchronized (this) {
11994            if (r != null && !r.isolated) {
11995                // XXX Can't keep track of crash time for isolated processes,
11996                // since they don't have a persistent identity.
11997                mProcessCrashTimes.put(r.info.processName, r.uid,
11998                        SystemClock.uptimeMillis());
11999            }
12000            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12001                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12002            }
12003        }
12004
12005        if (appErrorIntent != null) {
12006            try {
12007                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12008            } catch (ActivityNotFoundException e) {
12009                Slog.w(TAG, "bug report receiver dissappeared", e);
12010            }
12011        }
12012    }
12013
12014    Intent createAppErrorIntentLocked(ProcessRecord r,
12015            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12016        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12017        if (report == null) {
12018            return null;
12019        }
12020        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12021        result.setComponent(r.errorReportReceiver);
12022        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12023        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12024        return result;
12025    }
12026
12027    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12028            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12029        if (r.errorReportReceiver == null) {
12030            return null;
12031        }
12032
12033        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12034            return null;
12035        }
12036
12037        ApplicationErrorReport report = new ApplicationErrorReport();
12038        report.packageName = r.info.packageName;
12039        report.installerPackageName = r.errorReportReceiver.getPackageName();
12040        report.processName = r.processName;
12041        report.time = timeMillis;
12042        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12043
12044        if (r.crashing || r.forceCrashReport) {
12045            report.type = ApplicationErrorReport.TYPE_CRASH;
12046            report.crashInfo = crashInfo;
12047        } else if (r.notResponding) {
12048            report.type = ApplicationErrorReport.TYPE_ANR;
12049            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12050
12051            report.anrInfo.activity = r.notRespondingReport.tag;
12052            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12053            report.anrInfo.info = r.notRespondingReport.longMsg;
12054        }
12055
12056        return report;
12057    }
12058
12059    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12060        enforceNotIsolatedCaller("getProcessesInErrorState");
12061        // assume our apps are happy - lazy create the list
12062        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12063
12064        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12065                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12066        int userId = UserHandle.getUserId(Binder.getCallingUid());
12067
12068        synchronized (this) {
12069
12070            // iterate across all processes
12071            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12072                ProcessRecord app = mLruProcesses.get(i);
12073                if (!allUsers && app.userId != userId) {
12074                    continue;
12075                }
12076                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12077                    // This one's in trouble, so we'll generate a report for it
12078                    // crashes are higher priority (in case there's a crash *and* an anr)
12079                    ActivityManager.ProcessErrorStateInfo report = null;
12080                    if (app.crashing) {
12081                        report = app.crashingReport;
12082                    } else if (app.notResponding) {
12083                        report = app.notRespondingReport;
12084                    }
12085
12086                    if (report != null) {
12087                        if (errList == null) {
12088                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12089                        }
12090                        errList.add(report);
12091                    } else {
12092                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12093                                " crashing = " + app.crashing +
12094                                " notResponding = " + app.notResponding);
12095                    }
12096                }
12097            }
12098        }
12099
12100        return errList;
12101    }
12102
12103    static int procStateToImportance(int procState, int memAdj,
12104            ActivityManager.RunningAppProcessInfo currApp) {
12105        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12106        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12107            currApp.lru = memAdj;
12108        } else {
12109            currApp.lru = 0;
12110        }
12111        return imp;
12112    }
12113
12114    private void fillInProcMemInfo(ProcessRecord app,
12115            ActivityManager.RunningAppProcessInfo outInfo) {
12116        outInfo.pid = app.pid;
12117        outInfo.uid = app.info.uid;
12118        if (mHeavyWeightProcess == app) {
12119            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12120        }
12121        if (app.persistent) {
12122            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12123        }
12124        if (app.activities.size() > 0) {
12125            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12126        }
12127        outInfo.lastTrimLevel = app.trimMemoryLevel;
12128        int adj = app.curAdj;
12129        int procState = app.curProcState;
12130        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12131        outInfo.importanceReasonCode = app.adjTypeCode;
12132        outInfo.processState = app.curProcState;
12133    }
12134
12135    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12136        enforceNotIsolatedCaller("getRunningAppProcesses");
12137        // Lazy instantiation of list
12138        List<ActivityManager.RunningAppProcessInfo> runList = null;
12139        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12140                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12141        int userId = UserHandle.getUserId(Binder.getCallingUid());
12142        synchronized (this) {
12143            // Iterate across all processes
12144            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12145                ProcessRecord app = mLruProcesses.get(i);
12146                if (!allUsers && app.userId != userId) {
12147                    continue;
12148                }
12149                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12150                    // Generate process state info for running application
12151                    ActivityManager.RunningAppProcessInfo currApp =
12152                        new ActivityManager.RunningAppProcessInfo(app.processName,
12153                                app.pid, app.getPackageList());
12154                    fillInProcMemInfo(app, currApp);
12155                    if (app.adjSource instanceof ProcessRecord) {
12156                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12157                        currApp.importanceReasonImportance =
12158                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12159                                        app.adjSourceProcState);
12160                    } else if (app.adjSource instanceof ActivityRecord) {
12161                        ActivityRecord r = (ActivityRecord)app.adjSource;
12162                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12163                    }
12164                    if (app.adjTarget instanceof ComponentName) {
12165                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12166                    }
12167                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12168                    //        + " lru=" + currApp.lru);
12169                    if (runList == null) {
12170                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12171                    }
12172                    runList.add(currApp);
12173                }
12174            }
12175        }
12176        return runList;
12177    }
12178
12179    public List<ApplicationInfo> getRunningExternalApplications() {
12180        enforceNotIsolatedCaller("getRunningExternalApplications");
12181        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12182        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12183        if (runningApps != null && runningApps.size() > 0) {
12184            Set<String> extList = new HashSet<String>();
12185            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12186                if (app.pkgList != null) {
12187                    for (String pkg : app.pkgList) {
12188                        extList.add(pkg);
12189                    }
12190                }
12191            }
12192            IPackageManager pm = AppGlobals.getPackageManager();
12193            for (String pkg : extList) {
12194                try {
12195                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12196                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12197                        retList.add(info);
12198                    }
12199                } catch (RemoteException e) {
12200                }
12201            }
12202        }
12203        return retList;
12204    }
12205
12206    @Override
12207    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12208        enforceNotIsolatedCaller("getMyMemoryState");
12209        synchronized (this) {
12210            ProcessRecord proc;
12211            synchronized (mPidsSelfLocked) {
12212                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12213            }
12214            fillInProcMemInfo(proc, outInfo);
12215        }
12216    }
12217
12218    @Override
12219    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12220        if (checkCallingPermission(android.Manifest.permission.DUMP)
12221                != PackageManager.PERMISSION_GRANTED) {
12222            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12223                    + Binder.getCallingPid()
12224                    + ", uid=" + Binder.getCallingUid()
12225                    + " without permission "
12226                    + android.Manifest.permission.DUMP);
12227            return;
12228        }
12229
12230        boolean dumpAll = false;
12231        boolean dumpClient = false;
12232        String dumpPackage = null;
12233
12234        int opti = 0;
12235        while (opti < args.length) {
12236            String opt = args[opti];
12237            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12238                break;
12239            }
12240            opti++;
12241            if ("-a".equals(opt)) {
12242                dumpAll = true;
12243            } else if ("-c".equals(opt)) {
12244                dumpClient = true;
12245            } else if ("-h".equals(opt)) {
12246                pw.println("Activity manager dump options:");
12247                pw.println("  [-a] [-c] [-h] [cmd] ...");
12248                pw.println("  cmd may be one of:");
12249                pw.println("    a[ctivities]: activity stack state");
12250                pw.println("    r[recents]: recent activities state");
12251                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12252                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12253                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12254                pw.println("    o[om]: out of memory management");
12255                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12256                pw.println("    provider [COMP_SPEC]: provider client-side state");
12257                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12258                pw.println("    service [COMP_SPEC]: service client-side state");
12259                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12260                pw.println("    all: dump all activities");
12261                pw.println("    top: dump the top activity");
12262                pw.println("    write: write all pending state to storage");
12263                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12264                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12265                pw.println("    a partial substring in a component name, a");
12266                pw.println("    hex object identifier.");
12267                pw.println("  -a: include all available server state.");
12268                pw.println("  -c: include client state.");
12269                return;
12270            } else {
12271                pw.println("Unknown argument: " + opt + "; use -h for help");
12272            }
12273        }
12274
12275        long origId = Binder.clearCallingIdentity();
12276        boolean more = false;
12277        // Is the caller requesting to dump a particular piece of data?
12278        if (opti < args.length) {
12279            String cmd = args[opti];
12280            opti++;
12281            if ("activities".equals(cmd) || "a".equals(cmd)) {
12282                synchronized (this) {
12283                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12284                }
12285            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12286                synchronized (this) {
12287                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12288                }
12289            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12290                String[] newArgs;
12291                String name;
12292                if (opti >= args.length) {
12293                    name = null;
12294                    newArgs = EMPTY_STRING_ARRAY;
12295                } else {
12296                    name = args[opti];
12297                    opti++;
12298                    newArgs = new String[args.length - opti];
12299                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12300                            args.length - opti);
12301                }
12302                synchronized (this) {
12303                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12304                }
12305            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12306                String[] newArgs;
12307                String name;
12308                if (opti >= args.length) {
12309                    name = null;
12310                    newArgs = EMPTY_STRING_ARRAY;
12311                } else {
12312                    name = args[opti];
12313                    opti++;
12314                    newArgs = new String[args.length - opti];
12315                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12316                            args.length - opti);
12317                }
12318                synchronized (this) {
12319                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12320                }
12321            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12322                String[] newArgs;
12323                String name;
12324                if (opti >= args.length) {
12325                    name = null;
12326                    newArgs = EMPTY_STRING_ARRAY;
12327                } else {
12328                    name = args[opti];
12329                    opti++;
12330                    newArgs = new String[args.length - opti];
12331                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12332                            args.length - opti);
12333                }
12334                synchronized (this) {
12335                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12336                }
12337            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12338                synchronized (this) {
12339                    dumpOomLocked(fd, pw, args, opti, true);
12340                }
12341            } else if ("provider".equals(cmd)) {
12342                String[] newArgs;
12343                String name;
12344                if (opti >= args.length) {
12345                    name = null;
12346                    newArgs = EMPTY_STRING_ARRAY;
12347                } else {
12348                    name = args[opti];
12349                    opti++;
12350                    newArgs = new String[args.length - opti];
12351                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12352                }
12353                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12354                    pw.println("No providers match: " + name);
12355                    pw.println("Use -h for help.");
12356                }
12357            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12358                synchronized (this) {
12359                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12360                }
12361            } else if ("service".equals(cmd)) {
12362                String[] newArgs;
12363                String name;
12364                if (opti >= args.length) {
12365                    name = null;
12366                    newArgs = EMPTY_STRING_ARRAY;
12367                } else {
12368                    name = args[opti];
12369                    opti++;
12370                    newArgs = new String[args.length - opti];
12371                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12372                            args.length - opti);
12373                }
12374                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12375                    pw.println("No services match: " + name);
12376                    pw.println("Use -h for help.");
12377                }
12378            } else if ("package".equals(cmd)) {
12379                String[] newArgs;
12380                if (opti >= args.length) {
12381                    pw.println("package: no package name specified");
12382                    pw.println("Use -h for help.");
12383                } else {
12384                    dumpPackage = args[opti];
12385                    opti++;
12386                    newArgs = new String[args.length - opti];
12387                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12388                            args.length - opti);
12389                    args = newArgs;
12390                    opti = 0;
12391                    more = true;
12392                }
12393            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12394                synchronized (this) {
12395                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12396                }
12397            } else if ("write".equals(cmd)) {
12398                mTaskPersister.flush();
12399                pw.println("All tasks persisted.");
12400                return;
12401            } else {
12402                // Dumping a single activity?
12403                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12404                    pw.println("Bad activity command, or no activities match: " + cmd);
12405                    pw.println("Use -h for help.");
12406                }
12407            }
12408            if (!more) {
12409                Binder.restoreCallingIdentity(origId);
12410                return;
12411            }
12412        }
12413
12414        // No piece of data specified, dump everything.
12415        synchronized (this) {
12416            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12417            pw.println();
12418            if (dumpAll) {
12419                pw.println("-------------------------------------------------------------------------------");
12420            }
12421            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12422            pw.println();
12423            if (dumpAll) {
12424                pw.println("-------------------------------------------------------------------------------");
12425            }
12426            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12427            pw.println();
12428            if (dumpAll) {
12429                pw.println("-------------------------------------------------------------------------------");
12430            }
12431            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12432            pw.println();
12433            if (dumpAll) {
12434                pw.println("-------------------------------------------------------------------------------");
12435            }
12436            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12437            pw.println();
12438            if (dumpAll) {
12439                pw.println("-------------------------------------------------------------------------------");
12440            }
12441            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12442            pw.println();
12443            if (dumpAll) {
12444                pw.println("-------------------------------------------------------------------------------");
12445            }
12446            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12447        }
12448        Binder.restoreCallingIdentity(origId);
12449    }
12450
12451    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12452            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12453        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12454
12455        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12456                dumpPackage);
12457        boolean needSep = printedAnything;
12458
12459        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12460                dumpPackage, needSep, "  mFocusedActivity: ");
12461        if (printed) {
12462            printedAnything = true;
12463            needSep = false;
12464        }
12465
12466        if (dumpPackage == null) {
12467            if (needSep) {
12468                pw.println();
12469            }
12470            needSep = true;
12471            printedAnything = true;
12472            mStackSupervisor.dump(pw, "  ");
12473        }
12474
12475        if (!printedAnything) {
12476            pw.println("  (nothing)");
12477        }
12478    }
12479
12480    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12481            int opti, boolean dumpAll, String dumpPackage) {
12482        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12483
12484        boolean printedAnything = false;
12485
12486        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12487            boolean printedHeader = false;
12488
12489            final int N = mRecentTasks.size();
12490            for (int i=0; i<N; i++) {
12491                TaskRecord tr = mRecentTasks.get(i);
12492                if (dumpPackage != null) {
12493                    if (tr.realActivity == null ||
12494                            !dumpPackage.equals(tr.realActivity)) {
12495                        continue;
12496                    }
12497                }
12498                if (!printedHeader) {
12499                    pw.println("  Recent tasks:");
12500                    printedHeader = true;
12501                    printedAnything = true;
12502                }
12503                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12504                        pw.println(tr);
12505                if (dumpAll) {
12506                    mRecentTasks.get(i).dump(pw, "    ");
12507                }
12508            }
12509        }
12510
12511        if (!printedAnything) {
12512            pw.println("  (nothing)");
12513        }
12514    }
12515
12516    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12517            int opti, boolean dumpAll, String dumpPackage) {
12518        boolean needSep = false;
12519        boolean printedAnything = false;
12520        int numPers = 0;
12521
12522        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12523
12524        if (dumpAll) {
12525            final int NP = mProcessNames.getMap().size();
12526            for (int ip=0; ip<NP; ip++) {
12527                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12528                final int NA = procs.size();
12529                for (int ia=0; ia<NA; ia++) {
12530                    ProcessRecord r = procs.valueAt(ia);
12531                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12532                        continue;
12533                    }
12534                    if (!needSep) {
12535                        pw.println("  All known processes:");
12536                        needSep = true;
12537                        printedAnything = true;
12538                    }
12539                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12540                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12541                        pw.print(" "); pw.println(r);
12542                    r.dump(pw, "    ");
12543                    if (r.persistent) {
12544                        numPers++;
12545                    }
12546                }
12547            }
12548        }
12549
12550        if (mIsolatedProcesses.size() > 0) {
12551            boolean printed = false;
12552            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12553                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12554                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12555                    continue;
12556                }
12557                if (!printed) {
12558                    if (needSep) {
12559                        pw.println();
12560                    }
12561                    pw.println("  Isolated process list (sorted by uid):");
12562                    printedAnything = true;
12563                    printed = true;
12564                    needSep = true;
12565                }
12566                pw.println(String.format("%sIsolated #%2d: %s",
12567                        "    ", i, r.toString()));
12568            }
12569        }
12570
12571        if (mLruProcesses.size() > 0) {
12572            if (needSep) {
12573                pw.println();
12574            }
12575            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12576                    pw.print(" total, non-act at ");
12577                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12578                    pw.print(", non-svc at ");
12579                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12580                    pw.println("):");
12581            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12582            needSep = true;
12583            printedAnything = true;
12584        }
12585
12586        if (dumpAll || dumpPackage != null) {
12587            synchronized (mPidsSelfLocked) {
12588                boolean printed = false;
12589                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12590                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12591                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12592                        continue;
12593                    }
12594                    if (!printed) {
12595                        if (needSep) pw.println();
12596                        needSep = true;
12597                        pw.println("  PID mappings:");
12598                        printed = true;
12599                        printedAnything = true;
12600                    }
12601                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12602                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12603                }
12604            }
12605        }
12606
12607        if (mForegroundProcesses.size() > 0) {
12608            synchronized (mPidsSelfLocked) {
12609                boolean printed = false;
12610                for (int i=0; i<mForegroundProcesses.size(); i++) {
12611                    ProcessRecord r = mPidsSelfLocked.get(
12612                            mForegroundProcesses.valueAt(i).pid);
12613                    if (dumpPackage != null && (r == null
12614                            || !r.pkgList.containsKey(dumpPackage))) {
12615                        continue;
12616                    }
12617                    if (!printed) {
12618                        if (needSep) pw.println();
12619                        needSep = true;
12620                        pw.println("  Foreground Processes:");
12621                        printed = true;
12622                        printedAnything = true;
12623                    }
12624                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12625                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12626                }
12627            }
12628        }
12629
12630        if (mPersistentStartingProcesses.size() > 0) {
12631            if (needSep) pw.println();
12632            needSep = true;
12633            printedAnything = true;
12634            pw.println("  Persisent processes that are starting:");
12635            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12636                    "Starting Norm", "Restarting PERS", dumpPackage);
12637        }
12638
12639        if (mRemovedProcesses.size() > 0) {
12640            if (needSep) pw.println();
12641            needSep = true;
12642            printedAnything = true;
12643            pw.println("  Processes that are being removed:");
12644            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12645                    "Removed Norm", "Removed PERS", dumpPackage);
12646        }
12647
12648        if (mProcessesOnHold.size() > 0) {
12649            if (needSep) pw.println();
12650            needSep = true;
12651            printedAnything = true;
12652            pw.println("  Processes that are on old until the system is ready:");
12653            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12654                    "OnHold Norm", "OnHold PERS", dumpPackage);
12655        }
12656
12657        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12658
12659        if (mProcessCrashTimes.getMap().size() > 0) {
12660            boolean printed = false;
12661            long now = SystemClock.uptimeMillis();
12662            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12663            final int NP = pmap.size();
12664            for (int ip=0; ip<NP; ip++) {
12665                String pname = pmap.keyAt(ip);
12666                SparseArray<Long> uids = pmap.valueAt(ip);
12667                final int N = uids.size();
12668                for (int i=0; i<N; i++) {
12669                    int puid = uids.keyAt(i);
12670                    ProcessRecord r = mProcessNames.get(pname, puid);
12671                    if (dumpPackage != null && (r == null
12672                            || !r.pkgList.containsKey(dumpPackage))) {
12673                        continue;
12674                    }
12675                    if (!printed) {
12676                        if (needSep) pw.println();
12677                        needSep = true;
12678                        pw.println("  Time since processes crashed:");
12679                        printed = true;
12680                        printedAnything = true;
12681                    }
12682                    pw.print("    Process "); pw.print(pname);
12683                            pw.print(" uid "); pw.print(puid);
12684                            pw.print(": last crashed ");
12685                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12686                            pw.println(" ago");
12687                }
12688            }
12689        }
12690
12691        if (mBadProcesses.getMap().size() > 0) {
12692            boolean printed = false;
12693            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12694            final int NP = pmap.size();
12695            for (int ip=0; ip<NP; ip++) {
12696                String pname = pmap.keyAt(ip);
12697                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12698                final int N = uids.size();
12699                for (int i=0; i<N; i++) {
12700                    int puid = uids.keyAt(i);
12701                    ProcessRecord r = mProcessNames.get(pname, puid);
12702                    if (dumpPackage != null && (r == null
12703                            || !r.pkgList.containsKey(dumpPackage))) {
12704                        continue;
12705                    }
12706                    if (!printed) {
12707                        if (needSep) pw.println();
12708                        needSep = true;
12709                        pw.println("  Bad processes:");
12710                        printedAnything = true;
12711                    }
12712                    BadProcessInfo info = uids.valueAt(i);
12713                    pw.print("    Bad process "); pw.print(pname);
12714                            pw.print(" uid "); pw.print(puid);
12715                            pw.print(": crashed at time "); pw.println(info.time);
12716                    if (info.shortMsg != null) {
12717                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12718                    }
12719                    if (info.longMsg != null) {
12720                        pw.print("      Long msg: "); pw.println(info.longMsg);
12721                    }
12722                    if (info.stack != null) {
12723                        pw.println("      Stack:");
12724                        int lastPos = 0;
12725                        for (int pos=0; pos<info.stack.length(); pos++) {
12726                            if (info.stack.charAt(pos) == '\n') {
12727                                pw.print("        ");
12728                                pw.write(info.stack, lastPos, pos-lastPos);
12729                                pw.println();
12730                                lastPos = pos+1;
12731                            }
12732                        }
12733                        if (lastPos < info.stack.length()) {
12734                            pw.print("        ");
12735                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12736                            pw.println();
12737                        }
12738                    }
12739                }
12740            }
12741        }
12742
12743        if (dumpPackage == null) {
12744            pw.println();
12745            needSep = false;
12746            pw.println("  mStartedUsers:");
12747            for (int i=0; i<mStartedUsers.size(); i++) {
12748                UserStartedState uss = mStartedUsers.valueAt(i);
12749                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12750                        pw.print(": "); uss.dump("", pw);
12751            }
12752            pw.print("  mStartedUserArray: [");
12753            for (int i=0; i<mStartedUserArray.length; i++) {
12754                if (i > 0) pw.print(", ");
12755                pw.print(mStartedUserArray[i]);
12756            }
12757            pw.println("]");
12758            pw.print("  mUserLru: [");
12759            for (int i=0; i<mUserLru.size(); i++) {
12760                if (i > 0) pw.print(", ");
12761                pw.print(mUserLru.get(i));
12762            }
12763            pw.println("]");
12764            if (dumpAll) {
12765                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12766            }
12767            synchronized (mUserProfileGroupIdsSelfLocked) {
12768                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12769                    pw.println("  mUserProfileGroupIds:");
12770                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12771                        pw.print("    User #");
12772                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12773                        pw.print(" -> profile #");
12774                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12775                    }
12776                }
12777            }
12778        }
12779        if (mHomeProcess != null && (dumpPackage == null
12780                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12781            if (needSep) {
12782                pw.println();
12783                needSep = false;
12784            }
12785            pw.println("  mHomeProcess: " + mHomeProcess);
12786        }
12787        if (mPreviousProcess != null && (dumpPackage == null
12788                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12789            if (needSep) {
12790                pw.println();
12791                needSep = false;
12792            }
12793            pw.println("  mPreviousProcess: " + mPreviousProcess);
12794        }
12795        if (dumpAll) {
12796            StringBuilder sb = new StringBuilder(128);
12797            sb.append("  mPreviousProcessVisibleTime: ");
12798            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12799            pw.println(sb);
12800        }
12801        if (mHeavyWeightProcess != null && (dumpPackage == null
12802                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12803            if (needSep) {
12804                pw.println();
12805                needSep = false;
12806            }
12807            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12808        }
12809        if (dumpPackage == null) {
12810            pw.println("  mConfiguration: " + mConfiguration);
12811        }
12812        if (dumpAll) {
12813            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12814            if (mCompatModePackages.getPackages().size() > 0) {
12815                boolean printed = false;
12816                for (Map.Entry<String, Integer> entry
12817                        : mCompatModePackages.getPackages().entrySet()) {
12818                    String pkg = entry.getKey();
12819                    int mode = entry.getValue();
12820                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12821                        continue;
12822                    }
12823                    if (!printed) {
12824                        pw.println("  mScreenCompatPackages:");
12825                        printed = true;
12826                    }
12827                    pw.print("    "); pw.print(pkg); pw.print(": ");
12828                            pw.print(mode); pw.println();
12829                }
12830            }
12831        }
12832        if (dumpPackage == null) {
12833            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12834                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12835                        + " mLockScreenShown " + lockScreenShownToString());
12836            }
12837            if (mShuttingDown || mRunningVoice) {
12838                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12839            }
12840        }
12841        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12842                || mOrigWaitForDebugger) {
12843            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12844                    || dumpPackage.equals(mOrigDebugApp)) {
12845                if (needSep) {
12846                    pw.println();
12847                    needSep = false;
12848                }
12849                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12850                        + " mDebugTransient=" + mDebugTransient
12851                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12852            }
12853        }
12854        if (mOpenGlTraceApp != null) {
12855            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12856                if (needSep) {
12857                    pw.println();
12858                    needSep = false;
12859                }
12860                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12861            }
12862        }
12863        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12864                || mProfileFd != null) {
12865            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12866                if (needSep) {
12867                    pw.println();
12868                    needSep = false;
12869                }
12870                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12871                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12872                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12873                        + mAutoStopProfiler);
12874                pw.println("  mProfileType=" + mProfileType);
12875            }
12876        }
12877        if (dumpPackage == null) {
12878            if (mAlwaysFinishActivities || mController != null) {
12879                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12880                        + " mController=" + mController);
12881            }
12882            if (dumpAll) {
12883                pw.println("  Total persistent processes: " + numPers);
12884                pw.println("  mProcessesReady=" + mProcessesReady
12885                        + " mSystemReady=" + mSystemReady
12886                        + " mBooted=" + mBooted
12887                        + " mFactoryTest=" + mFactoryTest);
12888                pw.println("  mBooting=" + mBooting
12889                        + " mCallFinishBooting=" + mCallFinishBooting
12890                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12891                pw.print("  mLastPowerCheckRealtime=");
12892                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12893                        pw.println("");
12894                pw.print("  mLastPowerCheckUptime=");
12895                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12896                        pw.println("");
12897                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12898                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12899                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12900                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12901                        + " (" + mLruProcesses.size() + " total)"
12902                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12903                        + " mNumServiceProcs=" + mNumServiceProcs
12904                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12905                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12906                        + " mLastMemoryLevel" + mLastMemoryLevel
12907                        + " mLastNumProcesses" + mLastNumProcesses);
12908                long now = SystemClock.uptimeMillis();
12909                pw.print("  mLastIdleTime=");
12910                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12911                        pw.print(" mLowRamSinceLastIdle=");
12912                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12913                        pw.println();
12914            }
12915        }
12916
12917        if (!printedAnything) {
12918            pw.println("  (nothing)");
12919        }
12920    }
12921
12922    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12923            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12924        if (mProcessesToGc.size() > 0) {
12925            boolean printed = false;
12926            long now = SystemClock.uptimeMillis();
12927            for (int i=0; i<mProcessesToGc.size(); i++) {
12928                ProcessRecord proc = mProcessesToGc.get(i);
12929                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12930                    continue;
12931                }
12932                if (!printed) {
12933                    if (needSep) pw.println();
12934                    needSep = true;
12935                    pw.println("  Processes that are waiting to GC:");
12936                    printed = true;
12937                }
12938                pw.print("    Process "); pw.println(proc);
12939                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12940                        pw.print(", last gced=");
12941                        pw.print(now-proc.lastRequestedGc);
12942                        pw.print(" ms ago, last lowMem=");
12943                        pw.print(now-proc.lastLowMemory);
12944                        pw.println(" ms ago");
12945
12946            }
12947        }
12948        return needSep;
12949    }
12950
12951    void printOomLevel(PrintWriter pw, String name, int adj) {
12952        pw.print("    ");
12953        if (adj >= 0) {
12954            pw.print(' ');
12955            if (adj < 10) pw.print(' ');
12956        } else {
12957            if (adj > -10) pw.print(' ');
12958        }
12959        pw.print(adj);
12960        pw.print(": ");
12961        pw.print(name);
12962        pw.print(" (");
12963        pw.print(mProcessList.getMemLevel(adj)/1024);
12964        pw.println(" kB)");
12965    }
12966
12967    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12968            int opti, boolean dumpAll) {
12969        boolean needSep = false;
12970
12971        if (mLruProcesses.size() > 0) {
12972            if (needSep) pw.println();
12973            needSep = true;
12974            pw.println("  OOM levels:");
12975            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12976            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12977            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12978            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12979            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12980            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12981            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12982            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12983            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12984            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12985            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12986            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12987            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12988            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12989
12990            if (needSep) pw.println();
12991            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12992                    pw.print(" total, non-act at ");
12993                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12994                    pw.print(", non-svc at ");
12995                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12996                    pw.println("):");
12997            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12998            needSep = true;
12999        }
13000
13001        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13002
13003        pw.println();
13004        pw.println("  mHomeProcess: " + mHomeProcess);
13005        pw.println("  mPreviousProcess: " + mPreviousProcess);
13006        if (mHeavyWeightProcess != null) {
13007            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13008        }
13009
13010        return true;
13011    }
13012
13013    /**
13014     * There are three ways to call this:
13015     *  - no provider specified: dump all the providers
13016     *  - a flattened component name that matched an existing provider was specified as the
13017     *    first arg: dump that one provider
13018     *  - the first arg isn't the flattened component name of an existing provider:
13019     *    dump all providers whose component contains the first arg as a substring
13020     */
13021    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13022            int opti, boolean dumpAll) {
13023        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13024    }
13025
13026    static class ItemMatcher {
13027        ArrayList<ComponentName> components;
13028        ArrayList<String> strings;
13029        ArrayList<Integer> objects;
13030        boolean all;
13031
13032        ItemMatcher() {
13033            all = true;
13034        }
13035
13036        void build(String name) {
13037            ComponentName componentName = ComponentName.unflattenFromString(name);
13038            if (componentName != null) {
13039                if (components == null) {
13040                    components = new ArrayList<ComponentName>();
13041                }
13042                components.add(componentName);
13043                all = false;
13044            } else {
13045                int objectId = 0;
13046                // Not a '/' separated full component name; maybe an object ID?
13047                try {
13048                    objectId = Integer.parseInt(name, 16);
13049                    if (objects == null) {
13050                        objects = new ArrayList<Integer>();
13051                    }
13052                    objects.add(objectId);
13053                    all = false;
13054                } catch (RuntimeException e) {
13055                    // Not an integer; just do string match.
13056                    if (strings == null) {
13057                        strings = new ArrayList<String>();
13058                    }
13059                    strings.add(name);
13060                    all = false;
13061                }
13062            }
13063        }
13064
13065        int build(String[] args, int opti) {
13066            for (; opti<args.length; opti++) {
13067                String name = args[opti];
13068                if ("--".equals(name)) {
13069                    return opti+1;
13070                }
13071                build(name);
13072            }
13073            return opti;
13074        }
13075
13076        boolean match(Object object, ComponentName comp) {
13077            if (all) {
13078                return true;
13079            }
13080            if (components != null) {
13081                for (int i=0; i<components.size(); i++) {
13082                    if (components.get(i).equals(comp)) {
13083                        return true;
13084                    }
13085                }
13086            }
13087            if (objects != null) {
13088                for (int i=0; i<objects.size(); i++) {
13089                    if (System.identityHashCode(object) == objects.get(i)) {
13090                        return true;
13091                    }
13092                }
13093            }
13094            if (strings != null) {
13095                String flat = comp.flattenToString();
13096                for (int i=0; i<strings.size(); i++) {
13097                    if (flat.contains(strings.get(i))) {
13098                        return true;
13099                    }
13100                }
13101            }
13102            return false;
13103        }
13104    }
13105
13106    /**
13107     * There are three things that cmd can be:
13108     *  - a flattened component name that matches an existing activity
13109     *  - the cmd arg isn't the flattened component name of an existing activity:
13110     *    dump all activity whose component contains the cmd as a substring
13111     *  - A hex number of the ActivityRecord object instance.
13112     */
13113    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13114            int opti, boolean dumpAll) {
13115        ArrayList<ActivityRecord> activities;
13116
13117        synchronized (this) {
13118            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13119        }
13120
13121        if (activities.size() <= 0) {
13122            return false;
13123        }
13124
13125        String[] newArgs = new String[args.length - opti];
13126        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13127
13128        TaskRecord lastTask = null;
13129        boolean needSep = false;
13130        for (int i=activities.size()-1; i>=0; i--) {
13131            ActivityRecord r = activities.get(i);
13132            if (needSep) {
13133                pw.println();
13134            }
13135            needSep = true;
13136            synchronized (this) {
13137                if (lastTask != r.task) {
13138                    lastTask = r.task;
13139                    pw.print("TASK "); pw.print(lastTask.affinity);
13140                            pw.print(" id="); pw.println(lastTask.taskId);
13141                    if (dumpAll) {
13142                        lastTask.dump(pw, "  ");
13143                    }
13144                }
13145            }
13146            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13147        }
13148        return true;
13149    }
13150
13151    /**
13152     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13153     * there is a thread associated with the activity.
13154     */
13155    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13156            final ActivityRecord r, String[] args, boolean dumpAll) {
13157        String innerPrefix = prefix + "  ";
13158        synchronized (this) {
13159            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13160                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13161                    pw.print(" pid=");
13162                    if (r.app != null) pw.println(r.app.pid);
13163                    else pw.println("(not running)");
13164            if (dumpAll) {
13165                r.dump(pw, innerPrefix);
13166            }
13167        }
13168        if (r.app != null && r.app.thread != null) {
13169            // flush anything that is already in the PrintWriter since the thread is going
13170            // to write to the file descriptor directly
13171            pw.flush();
13172            try {
13173                TransferPipe tp = new TransferPipe();
13174                try {
13175                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13176                            r.appToken, innerPrefix, args);
13177                    tp.go(fd);
13178                } finally {
13179                    tp.kill();
13180                }
13181            } catch (IOException e) {
13182                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13183            } catch (RemoteException e) {
13184                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13185            }
13186        }
13187    }
13188
13189    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13190            int opti, boolean dumpAll, String dumpPackage) {
13191        boolean needSep = false;
13192        boolean onlyHistory = false;
13193        boolean printedAnything = false;
13194
13195        if ("history".equals(dumpPackage)) {
13196            if (opti < args.length && "-s".equals(args[opti])) {
13197                dumpAll = false;
13198            }
13199            onlyHistory = true;
13200            dumpPackage = null;
13201        }
13202
13203        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13204        if (!onlyHistory && dumpAll) {
13205            if (mRegisteredReceivers.size() > 0) {
13206                boolean printed = false;
13207                Iterator it = mRegisteredReceivers.values().iterator();
13208                while (it.hasNext()) {
13209                    ReceiverList r = (ReceiverList)it.next();
13210                    if (dumpPackage != null && (r.app == null ||
13211                            !dumpPackage.equals(r.app.info.packageName))) {
13212                        continue;
13213                    }
13214                    if (!printed) {
13215                        pw.println("  Registered Receivers:");
13216                        needSep = true;
13217                        printed = true;
13218                        printedAnything = true;
13219                    }
13220                    pw.print("  * "); pw.println(r);
13221                    r.dump(pw, "    ");
13222                }
13223            }
13224
13225            if (mReceiverResolver.dump(pw, needSep ?
13226                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13227                    "    ", dumpPackage, false, false)) {
13228                needSep = true;
13229                printedAnything = true;
13230            }
13231        }
13232
13233        for (BroadcastQueue q : mBroadcastQueues) {
13234            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13235            printedAnything |= needSep;
13236        }
13237
13238        needSep = true;
13239
13240        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13241            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13242                if (needSep) {
13243                    pw.println();
13244                }
13245                needSep = true;
13246                printedAnything = true;
13247                pw.print("  Sticky broadcasts for user ");
13248                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13249                StringBuilder sb = new StringBuilder(128);
13250                for (Map.Entry<String, ArrayList<Intent>> ent
13251                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13252                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13253                    if (dumpAll) {
13254                        pw.println(":");
13255                        ArrayList<Intent> intents = ent.getValue();
13256                        final int N = intents.size();
13257                        for (int i=0; i<N; i++) {
13258                            sb.setLength(0);
13259                            sb.append("    Intent: ");
13260                            intents.get(i).toShortString(sb, false, true, false, false);
13261                            pw.println(sb.toString());
13262                            Bundle bundle = intents.get(i).getExtras();
13263                            if (bundle != null) {
13264                                pw.print("      ");
13265                                pw.println(bundle.toString());
13266                            }
13267                        }
13268                    } else {
13269                        pw.println("");
13270                    }
13271                }
13272            }
13273        }
13274
13275        if (!onlyHistory && dumpAll) {
13276            pw.println();
13277            for (BroadcastQueue queue : mBroadcastQueues) {
13278                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13279                        + queue.mBroadcastsScheduled);
13280            }
13281            pw.println("  mHandler:");
13282            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13283            needSep = true;
13284            printedAnything = true;
13285        }
13286
13287        if (!printedAnything) {
13288            pw.println("  (nothing)");
13289        }
13290    }
13291
13292    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13293            int opti, boolean dumpAll, String dumpPackage) {
13294        boolean needSep;
13295        boolean printedAnything = false;
13296
13297        ItemMatcher matcher = new ItemMatcher();
13298        matcher.build(args, opti);
13299
13300        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13301
13302        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13303        printedAnything |= needSep;
13304
13305        if (mLaunchingProviders.size() > 0) {
13306            boolean printed = false;
13307            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13308                ContentProviderRecord r = mLaunchingProviders.get(i);
13309                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13310                    continue;
13311                }
13312                if (!printed) {
13313                    if (needSep) pw.println();
13314                    needSep = true;
13315                    pw.println("  Launching content providers:");
13316                    printed = true;
13317                    printedAnything = true;
13318                }
13319                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13320                        pw.println(r);
13321            }
13322        }
13323
13324        if (mGrantedUriPermissions.size() > 0) {
13325            boolean printed = false;
13326            int dumpUid = -2;
13327            if (dumpPackage != null) {
13328                try {
13329                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13330                } catch (NameNotFoundException e) {
13331                    dumpUid = -1;
13332                }
13333            }
13334            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13335                int uid = mGrantedUriPermissions.keyAt(i);
13336                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13337                    continue;
13338                }
13339                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13340                if (!printed) {
13341                    if (needSep) pw.println();
13342                    needSep = true;
13343                    pw.println("  Granted Uri Permissions:");
13344                    printed = true;
13345                    printedAnything = true;
13346                }
13347                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13348                for (UriPermission perm : perms.values()) {
13349                    pw.print("    "); pw.println(perm);
13350                    if (dumpAll) {
13351                        perm.dump(pw, "      ");
13352                    }
13353                }
13354            }
13355        }
13356
13357        if (!printedAnything) {
13358            pw.println("  (nothing)");
13359        }
13360    }
13361
13362    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13363            int opti, boolean dumpAll, String dumpPackage) {
13364        boolean printed = false;
13365
13366        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13367
13368        if (mIntentSenderRecords.size() > 0) {
13369            Iterator<WeakReference<PendingIntentRecord>> it
13370                    = mIntentSenderRecords.values().iterator();
13371            while (it.hasNext()) {
13372                WeakReference<PendingIntentRecord> ref = it.next();
13373                PendingIntentRecord rec = ref != null ? ref.get(): null;
13374                if (dumpPackage != null && (rec == null
13375                        || !dumpPackage.equals(rec.key.packageName))) {
13376                    continue;
13377                }
13378                printed = true;
13379                if (rec != null) {
13380                    pw.print("  * "); pw.println(rec);
13381                    if (dumpAll) {
13382                        rec.dump(pw, "    ");
13383                    }
13384                } else {
13385                    pw.print("  * "); pw.println(ref);
13386                }
13387            }
13388        }
13389
13390        if (!printed) {
13391            pw.println("  (nothing)");
13392        }
13393    }
13394
13395    private static final int dumpProcessList(PrintWriter pw,
13396            ActivityManagerService service, List list,
13397            String prefix, String normalLabel, String persistentLabel,
13398            String dumpPackage) {
13399        int numPers = 0;
13400        final int N = list.size()-1;
13401        for (int i=N; i>=0; i--) {
13402            ProcessRecord r = (ProcessRecord)list.get(i);
13403            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13404                continue;
13405            }
13406            pw.println(String.format("%s%s #%2d: %s",
13407                    prefix, (r.persistent ? persistentLabel : normalLabel),
13408                    i, r.toString()));
13409            if (r.persistent) {
13410                numPers++;
13411            }
13412        }
13413        return numPers;
13414    }
13415
13416    private static final boolean dumpProcessOomList(PrintWriter pw,
13417            ActivityManagerService service, List<ProcessRecord> origList,
13418            String prefix, String normalLabel, String persistentLabel,
13419            boolean inclDetails, String dumpPackage) {
13420
13421        ArrayList<Pair<ProcessRecord, Integer>> list
13422                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13423        for (int i=0; i<origList.size(); i++) {
13424            ProcessRecord r = origList.get(i);
13425            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13426                continue;
13427            }
13428            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13429        }
13430
13431        if (list.size() <= 0) {
13432            return false;
13433        }
13434
13435        Comparator<Pair<ProcessRecord, Integer>> comparator
13436                = new Comparator<Pair<ProcessRecord, Integer>>() {
13437            @Override
13438            public int compare(Pair<ProcessRecord, Integer> object1,
13439                    Pair<ProcessRecord, Integer> object2) {
13440                if (object1.first.setAdj != object2.first.setAdj) {
13441                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13442                }
13443                if (object1.second.intValue() != object2.second.intValue()) {
13444                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13445                }
13446                return 0;
13447            }
13448        };
13449
13450        Collections.sort(list, comparator);
13451
13452        final long curRealtime = SystemClock.elapsedRealtime();
13453        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13454        final long curUptime = SystemClock.uptimeMillis();
13455        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13456
13457        for (int i=list.size()-1; i>=0; i--) {
13458            ProcessRecord r = list.get(i).first;
13459            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13460            char schedGroup;
13461            switch (r.setSchedGroup) {
13462                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13463                    schedGroup = 'B';
13464                    break;
13465                case Process.THREAD_GROUP_DEFAULT:
13466                    schedGroup = 'F';
13467                    break;
13468                default:
13469                    schedGroup = '?';
13470                    break;
13471            }
13472            char foreground;
13473            if (r.foregroundActivities) {
13474                foreground = 'A';
13475            } else if (r.foregroundServices) {
13476                foreground = 'S';
13477            } else {
13478                foreground = ' ';
13479            }
13480            String procState = ProcessList.makeProcStateString(r.curProcState);
13481            pw.print(prefix);
13482            pw.print(r.persistent ? persistentLabel : normalLabel);
13483            pw.print(" #");
13484            int num = (origList.size()-1)-list.get(i).second;
13485            if (num < 10) pw.print(' ');
13486            pw.print(num);
13487            pw.print(": ");
13488            pw.print(oomAdj);
13489            pw.print(' ');
13490            pw.print(schedGroup);
13491            pw.print('/');
13492            pw.print(foreground);
13493            pw.print('/');
13494            pw.print(procState);
13495            pw.print(" trm:");
13496            if (r.trimMemoryLevel < 10) pw.print(' ');
13497            pw.print(r.trimMemoryLevel);
13498            pw.print(' ');
13499            pw.print(r.toShortString());
13500            pw.print(" (");
13501            pw.print(r.adjType);
13502            pw.println(')');
13503            if (r.adjSource != null || r.adjTarget != null) {
13504                pw.print(prefix);
13505                pw.print("    ");
13506                if (r.adjTarget instanceof ComponentName) {
13507                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13508                } else if (r.adjTarget != null) {
13509                    pw.print(r.adjTarget.toString());
13510                } else {
13511                    pw.print("{null}");
13512                }
13513                pw.print("<=");
13514                if (r.adjSource instanceof ProcessRecord) {
13515                    pw.print("Proc{");
13516                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13517                    pw.println("}");
13518                } else if (r.adjSource != null) {
13519                    pw.println(r.adjSource.toString());
13520                } else {
13521                    pw.println("{null}");
13522                }
13523            }
13524            if (inclDetails) {
13525                pw.print(prefix);
13526                pw.print("    ");
13527                pw.print("oom: max="); pw.print(r.maxAdj);
13528                pw.print(" curRaw="); pw.print(r.curRawAdj);
13529                pw.print(" setRaw="); pw.print(r.setRawAdj);
13530                pw.print(" cur="); pw.print(r.curAdj);
13531                pw.print(" set="); pw.println(r.setAdj);
13532                pw.print(prefix);
13533                pw.print("    ");
13534                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13535                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13536                pw.print(" lastPss="); pw.print(r.lastPss);
13537                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13538                pw.print(prefix);
13539                pw.print("    ");
13540                pw.print("cached="); pw.print(r.cached);
13541                pw.print(" empty="); pw.print(r.empty);
13542                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13543
13544                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13545                    if (r.lastWakeTime != 0) {
13546                        long wtime;
13547                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13548                        synchronized (stats) {
13549                            wtime = stats.getProcessWakeTime(r.info.uid,
13550                                    r.pid, curRealtime);
13551                        }
13552                        long timeUsed = wtime - r.lastWakeTime;
13553                        pw.print(prefix);
13554                        pw.print("    ");
13555                        pw.print("keep awake over ");
13556                        TimeUtils.formatDuration(realtimeSince, pw);
13557                        pw.print(" used ");
13558                        TimeUtils.formatDuration(timeUsed, pw);
13559                        pw.print(" (");
13560                        pw.print((timeUsed*100)/realtimeSince);
13561                        pw.println("%)");
13562                    }
13563                    if (r.lastCpuTime != 0) {
13564                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13565                        pw.print(prefix);
13566                        pw.print("    ");
13567                        pw.print("run cpu over ");
13568                        TimeUtils.formatDuration(uptimeSince, pw);
13569                        pw.print(" used ");
13570                        TimeUtils.formatDuration(timeUsed, pw);
13571                        pw.print(" (");
13572                        pw.print((timeUsed*100)/uptimeSince);
13573                        pw.println("%)");
13574                    }
13575                }
13576            }
13577        }
13578        return true;
13579    }
13580
13581    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13582            String[] args) {
13583        ArrayList<ProcessRecord> procs;
13584        synchronized (this) {
13585            if (args != null && args.length > start
13586                    && args[start].charAt(0) != '-') {
13587                procs = new ArrayList<ProcessRecord>();
13588                int pid = -1;
13589                try {
13590                    pid = Integer.parseInt(args[start]);
13591                } catch (NumberFormatException e) {
13592                }
13593                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13594                    ProcessRecord proc = mLruProcesses.get(i);
13595                    if (proc.pid == pid) {
13596                        procs.add(proc);
13597                    } else if (allPkgs && proc.pkgList != null
13598                            && proc.pkgList.containsKey(args[start])) {
13599                        procs.add(proc);
13600                    } else if (proc.processName.equals(args[start])) {
13601                        procs.add(proc);
13602                    }
13603                }
13604                if (procs.size() <= 0) {
13605                    return null;
13606                }
13607            } else {
13608                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13609            }
13610        }
13611        return procs;
13612    }
13613
13614    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13615            PrintWriter pw, String[] args) {
13616        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13617        if (procs == null) {
13618            pw.println("No process found for: " + args[0]);
13619            return;
13620        }
13621
13622        long uptime = SystemClock.uptimeMillis();
13623        long realtime = SystemClock.elapsedRealtime();
13624        pw.println("Applications Graphics Acceleration Info:");
13625        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13626
13627        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13628            ProcessRecord r = procs.get(i);
13629            if (r.thread != null) {
13630                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13631                pw.flush();
13632                try {
13633                    TransferPipe tp = new TransferPipe();
13634                    try {
13635                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13636                        tp.go(fd);
13637                    } finally {
13638                        tp.kill();
13639                    }
13640                } catch (IOException e) {
13641                    pw.println("Failure while dumping the app: " + r);
13642                    pw.flush();
13643                } catch (RemoteException e) {
13644                    pw.println("Got a RemoteException while dumping the app " + r);
13645                    pw.flush();
13646                }
13647            }
13648        }
13649    }
13650
13651    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13652        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13653        if (procs == null) {
13654            pw.println("No process found for: " + args[0]);
13655            return;
13656        }
13657
13658        pw.println("Applications Database Info:");
13659
13660        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13661            ProcessRecord r = procs.get(i);
13662            if (r.thread != null) {
13663                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13664                pw.flush();
13665                try {
13666                    TransferPipe tp = new TransferPipe();
13667                    try {
13668                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13669                        tp.go(fd);
13670                    } finally {
13671                        tp.kill();
13672                    }
13673                } catch (IOException e) {
13674                    pw.println("Failure while dumping the app: " + r);
13675                    pw.flush();
13676                } catch (RemoteException e) {
13677                    pw.println("Got a RemoteException while dumping the app " + r);
13678                    pw.flush();
13679                }
13680            }
13681        }
13682    }
13683
13684    final static class MemItem {
13685        final boolean isProc;
13686        final String label;
13687        final String shortLabel;
13688        final long pss;
13689        final int id;
13690        final boolean hasActivities;
13691        ArrayList<MemItem> subitems;
13692
13693        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13694                boolean _hasActivities) {
13695            isProc = true;
13696            label = _label;
13697            shortLabel = _shortLabel;
13698            pss = _pss;
13699            id = _id;
13700            hasActivities = _hasActivities;
13701        }
13702
13703        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13704            isProc = false;
13705            label = _label;
13706            shortLabel = _shortLabel;
13707            pss = _pss;
13708            id = _id;
13709            hasActivities = false;
13710        }
13711    }
13712
13713    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13714            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13715        if (sort && !isCompact) {
13716            Collections.sort(items, new Comparator<MemItem>() {
13717                @Override
13718                public int compare(MemItem lhs, MemItem rhs) {
13719                    if (lhs.pss < rhs.pss) {
13720                        return 1;
13721                    } else if (lhs.pss > rhs.pss) {
13722                        return -1;
13723                    }
13724                    return 0;
13725                }
13726            });
13727        }
13728
13729        for (int i=0; i<items.size(); i++) {
13730            MemItem mi = items.get(i);
13731            if (!isCompact) {
13732                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13733            } else if (mi.isProc) {
13734                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13735                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13736                pw.println(mi.hasActivities ? ",a" : ",e");
13737            } else {
13738                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13739                pw.println(mi.pss);
13740            }
13741            if (mi.subitems != null) {
13742                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13743                        true, isCompact);
13744            }
13745        }
13746    }
13747
13748    // These are in KB.
13749    static final long[] DUMP_MEM_BUCKETS = new long[] {
13750        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13751        120*1024, 160*1024, 200*1024,
13752        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13753        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13754    };
13755
13756    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13757            boolean stackLike) {
13758        int start = label.lastIndexOf('.');
13759        if (start >= 0) start++;
13760        else start = 0;
13761        int end = label.length();
13762        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13763            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13764                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13765                out.append(bucket);
13766                out.append(stackLike ? "MB." : "MB ");
13767                out.append(label, start, end);
13768                return;
13769            }
13770        }
13771        out.append(memKB/1024);
13772        out.append(stackLike ? "MB." : "MB ");
13773        out.append(label, start, end);
13774    }
13775
13776    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13777            ProcessList.NATIVE_ADJ,
13778            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13779            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13780            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13781            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13782            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13783            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13784    };
13785    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13786            "Native",
13787            "System", "Persistent", "Persistent Service", "Foreground",
13788            "Visible", "Perceptible",
13789            "Heavy Weight", "Backup",
13790            "A Services", "Home",
13791            "Previous", "B Services", "Cached"
13792    };
13793    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13794            "native",
13795            "sys", "pers", "persvc", "fore",
13796            "vis", "percept",
13797            "heavy", "backup",
13798            "servicea", "home",
13799            "prev", "serviceb", "cached"
13800    };
13801
13802    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13803            long realtime, boolean isCheckinRequest, boolean isCompact) {
13804        if (isCheckinRequest || isCompact) {
13805            // short checkin version
13806            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13807        } else {
13808            pw.println("Applications Memory Usage (kB):");
13809            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13810        }
13811    }
13812
13813    private static final int KSM_SHARED = 0;
13814    private static final int KSM_SHARING = 1;
13815    private static final int KSM_UNSHARED = 2;
13816    private static final int KSM_VOLATILE = 3;
13817
13818    private final long[] getKsmInfo() {
13819        long[] longOut = new long[4];
13820        final int[] SINGLE_LONG_FORMAT = new int[] {
13821            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13822        };
13823        long[] longTmp = new long[1];
13824        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13825                SINGLE_LONG_FORMAT, null, longTmp, null);
13826        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13827        longTmp[0] = 0;
13828        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13829                SINGLE_LONG_FORMAT, null, longTmp, null);
13830        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13831        longTmp[0] = 0;
13832        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13833                SINGLE_LONG_FORMAT, null, longTmp, null);
13834        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13835        longTmp[0] = 0;
13836        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13837                SINGLE_LONG_FORMAT, null, longTmp, null);
13838        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13839        return longOut;
13840    }
13841
13842    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13843            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13844        boolean dumpDetails = false;
13845        boolean dumpFullDetails = false;
13846        boolean dumpDalvik = false;
13847        boolean oomOnly = false;
13848        boolean isCompact = false;
13849        boolean localOnly = false;
13850        boolean packages = false;
13851
13852        int opti = 0;
13853        while (opti < args.length) {
13854            String opt = args[opti];
13855            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13856                break;
13857            }
13858            opti++;
13859            if ("-a".equals(opt)) {
13860                dumpDetails = true;
13861                dumpFullDetails = true;
13862                dumpDalvik = true;
13863            } else if ("-d".equals(opt)) {
13864                dumpDalvik = true;
13865            } else if ("-c".equals(opt)) {
13866                isCompact = true;
13867            } else if ("--oom".equals(opt)) {
13868                oomOnly = true;
13869            } else if ("--local".equals(opt)) {
13870                localOnly = true;
13871            } else if ("--package".equals(opt)) {
13872                packages = true;
13873            } else if ("-h".equals(opt)) {
13874                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13875                pw.println("  -a: include all available information for each process.");
13876                pw.println("  -d: include dalvik details when dumping process details.");
13877                pw.println("  -c: dump in a compact machine-parseable representation.");
13878                pw.println("  --oom: only show processes organized by oom adj.");
13879                pw.println("  --local: only collect details locally, don't call process.");
13880                pw.println("  --package: interpret process arg as package, dumping all");
13881                pw.println("             processes that have loaded that package.");
13882                pw.println("If [process] is specified it can be the name or ");
13883                pw.println("pid of a specific process to dump.");
13884                return;
13885            } else {
13886                pw.println("Unknown argument: " + opt + "; use -h for help");
13887            }
13888        }
13889
13890        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13891        long uptime = SystemClock.uptimeMillis();
13892        long realtime = SystemClock.elapsedRealtime();
13893        final long[] tmpLong = new long[1];
13894
13895        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13896        if (procs == null) {
13897            // No Java processes.  Maybe they want to print a native process.
13898            if (args != null && args.length > opti
13899                    && args[opti].charAt(0) != '-') {
13900                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13901                        = new ArrayList<ProcessCpuTracker.Stats>();
13902                updateCpuStatsNow();
13903                int findPid = -1;
13904                try {
13905                    findPid = Integer.parseInt(args[opti]);
13906                } catch (NumberFormatException e) {
13907                }
13908                synchronized (mProcessCpuTracker) {
13909                    final int N = mProcessCpuTracker.countStats();
13910                    for (int i=0; i<N; i++) {
13911                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13912                        if (st.pid == findPid || (st.baseName != null
13913                                && st.baseName.equals(args[opti]))) {
13914                            nativeProcs.add(st);
13915                        }
13916                    }
13917                }
13918                if (nativeProcs.size() > 0) {
13919                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13920                            isCompact);
13921                    Debug.MemoryInfo mi = null;
13922                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13923                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13924                        final int pid = r.pid;
13925                        if (!isCheckinRequest && dumpDetails) {
13926                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13927                        }
13928                        if (mi == null) {
13929                            mi = new Debug.MemoryInfo();
13930                        }
13931                        if (dumpDetails || (!brief && !oomOnly)) {
13932                            Debug.getMemoryInfo(pid, mi);
13933                        } else {
13934                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13935                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13936                        }
13937                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13938                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13939                        if (isCheckinRequest) {
13940                            pw.println();
13941                        }
13942                    }
13943                    return;
13944                }
13945            }
13946            pw.println("No process found for: " + args[opti]);
13947            return;
13948        }
13949
13950        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13951            dumpDetails = true;
13952        }
13953
13954        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13955
13956        String[] innerArgs = new String[args.length-opti];
13957        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13958
13959        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13960        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13961        long nativePss = 0;
13962        long dalvikPss = 0;
13963        long otherPss = 0;
13964        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13965
13966        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13967        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13968                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13969
13970        long totalPss = 0;
13971        long cachedPss = 0;
13972
13973        Debug.MemoryInfo mi = null;
13974        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13975            final ProcessRecord r = procs.get(i);
13976            final IApplicationThread thread;
13977            final int pid;
13978            final int oomAdj;
13979            final boolean hasActivities;
13980            synchronized (this) {
13981                thread = r.thread;
13982                pid = r.pid;
13983                oomAdj = r.getSetAdjWithServices();
13984                hasActivities = r.activities.size() > 0;
13985            }
13986            if (thread != null) {
13987                if (!isCheckinRequest && dumpDetails) {
13988                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13989                }
13990                if (mi == null) {
13991                    mi = new Debug.MemoryInfo();
13992                }
13993                if (dumpDetails || (!brief && !oomOnly)) {
13994                    Debug.getMemoryInfo(pid, mi);
13995                } else {
13996                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13997                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13998                }
13999                if (dumpDetails) {
14000                    if (localOnly) {
14001                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14002                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14003                        if (isCheckinRequest) {
14004                            pw.println();
14005                        }
14006                    } else {
14007                        try {
14008                            pw.flush();
14009                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14010                                    dumpDalvik, innerArgs);
14011                        } catch (RemoteException e) {
14012                            if (!isCheckinRequest) {
14013                                pw.println("Got RemoteException!");
14014                                pw.flush();
14015                            }
14016                        }
14017                    }
14018                }
14019
14020                final long myTotalPss = mi.getTotalPss();
14021                final long myTotalUss = mi.getTotalUss();
14022
14023                synchronized (this) {
14024                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14025                        // Record this for posterity if the process has been stable.
14026                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14027                    }
14028                }
14029
14030                if (!isCheckinRequest && mi != null) {
14031                    totalPss += myTotalPss;
14032                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14033                            (hasActivities ? " / activities)" : ")"),
14034                            r.processName, myTotalPss, pid, hasActivities);
14035                    procMems.add(pssItem);
14036                    procMemsMap.put(pid, pssItem);
14037
14038                    nativePss += mi.nativePss;
14039                    dalvikPss += mi.dalvikPss;
14040                    otherPss += mi.otherPss;
14041                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14042                        long mem = mi.getOtherPss(j);
14043                        miscPss[j] += mem;
14044                        otherPss -= mem;
14045                    }
14046
14047                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14048                        cachedPss += myTotalPss;
14049                    }
14050
14051                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14052                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14053                                || oomIndex == (oomPss.length-1)) {
14054                            oomPss[oomIndex] += myTotalPss;
14055                            if (oomProcs[oomIndex] == null) {
14056                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14057                            }
14058                            oomProcs[oomIndex].add(pssItem);
14059                            break;
14060                        }
14061                    }
14062                }
14063            }
14064        }
14065
14066        long nativeProcTotalPss = 0;
14067
14068        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14069            // If we are showing aggregations, also look for native processes to
14070            // include so that our aggregations are more accurate.
14071            updateCpuStatsNow();
14072            synchronized (mProcessCpuTracker) {
14073                final int N = mProcessCpuTracker.countStats();
14074                for (int i=0; i<N; i++) {
14075                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14076                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14077                        if (mi == null) {
14078                            mi = new Debug.MemoryInfo();
14079                        }
14080                        if (!brief && !oomOnly) {
14081                            Debug.getMemoryInfo(st.pid, mi);
14082                        } else {
14083                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14084                            mi.nativePrivateDirty = (int)tmpLong[0];
14085                        }
14086
14087                        final long myTotalPss = mi.getTotalPss();
14088                        totalPss += myTotalPss;
14089                        nativeProcTotalPss += myTotalPss;
14090
14091                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14092                                st.name, myTotalPss, st.pid, false);
14093                        procMems.add(pssItem);
14094
14095                        nativePss += mi.nativePss;
14096                        dalvikPss += mi.dalvikPss;
14097                        otherPss += mi.otherPss;
14098                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14099                            long mem = mi.getOtherPss(j);
14100                            miscPss[j] += mem;
14101                            otherPss -= mem;
14102                        }
14103                        oomPss[0] += myTotalPss;
14104                        if (oomProcs[0] == null) {
14105                            oomProcs[0] = new ArrayList<MemItem>();
14106                        }
14107                        oomProcs[0].add(pssItem);
14108                    }
14109                }
14110            }
14111
14112            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14113
14114            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14115            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14116            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14117            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14118                String label = Debug.MemoryInfo.getOtherLabel(j);
14119                catMems.add(new MemItem(label, label, miscPss[j], j));
14120            }
14121
14122            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14123            for (int j=0; j<oomPss.length; j++) {
14124                if (oomPss[j] != 0) {
14125                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14126                            : DUMP_MEM_OOM_LABEL[j];
14127                    MemItem item = new MemItem(label, label, oomPss[j],
14128                            DUMP_MEM_OOM_ADJ[j]);
14129                    item.subitems = oomProcs[j];
14130                    oomMems.add(item);
14131                }
14132            }
14133
14134            if (!brief && !oomOnly && !isCompact) {
14135                pw.println();
14136                pw.println("Total PSS by process:");
14137                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14138                pw.println();
14139            }
14140            if (!isCompact) {
14141                pw.println("Total PSS by OOM adjustment:");
14142            }
14143            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14144            if (!brief && !oomOnly) {
14145                PrintWriter out = categoryPw != null ? categoryPw : pw;
14146                if (!isCompact) {
14147                    out.println();
14148                    out.println("Total PSS by category:");
14149                }
14150                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14151            }
14152            if (!isCompact) {
14153                pw.println();
14154            }
14155            MemInfoReader memInfo = new MemInfoReader();
14156            memInfo.readMemInfo();
14157            if (nativeProcTotalPss > 0) {
14158                synchronized (this) {
14159                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14160                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14161                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14162                }
14163            }
14164            if (!brief) {
14165                if (!isCompact) {
14166                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14167                    pw.print(" kB (status ");
14168                    switch (mLastMemoryLevel) {
14169                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14170                            pw.println("normal)");
14171                            break;
14172                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14173                            pw.println("moderate)");
14174                            break;
14175                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14176                            pw.println("low)");
14177                            break;
14178                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14179                            pw.println("critical)");
14180                            break;
14181                        default:
14182                            pw.print(mLastMemoryLevel);
14183                            pw.println(")");
14184                            break;
14185                    }
14186                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14187                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14188                            pw.print(cachedPss); pw.print(" cached pss + ");
14189                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14190                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14191                } else {
14192                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14193                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14194                            + memInfo.getFreeSizeKb()); pw.print(",");
14195                    pw.println(totalPss - cachedPss);
14196                }
14197            }
14198            if (!isCompact) {
14199                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14200                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14201                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14202                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14203                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14204                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14205                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14206            }
14207            if (!brief) {
14208                if (memInfo.getZramTotalSizeKb() != 0) {
14209                    if (!isCompact) {
14210                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14211                                pw.print(" kB physical used for ");
14212                                pw.print(memInfo.getSwapTotalSizeKb()
14213                                        - memInfo.getSwapFreeSizeKb());
14214                                pw.print(" kB in swap (");
14215                                pw.print(memInfo.getSwapTotalSizeKb());
14216                                pw.println(" kB total swap)");
14217                    } else {
14218                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14219                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14220                                pw.println(memInfo.getSwapFreeSizeKb());
14221                    }
14222                }
14223                final long[] ksm = getKsmInfo();
14224                if (!isCompact) {
14225                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14226                            || ksm[KSM_VOLATILE] != 0) {
14227                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14228                                pw.print(" kB saved from shared ");
14229                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14230                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14231                                pw.print(" kB unshared; ");
14232                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14233                    }
14234                    pw.print("   Tuning: ");
14235                    pw.print(ActivityManager.staticGetMemoryClass());
14236                    pw.print(" (large ");
14237                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14238                    pw.print("), oom ");
14239                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14240                    pw.print(" kB");
14241                    pw.print(", restore limit ");
14242                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14243                    pw.print(" kB");
14244                    if (ActivityManager.isLowRamDeviceStatic()) {
14245                        pw.print(" (low-ram)");
14246                    }
14247                    if (ActivityManager.isHighEndGfx()) {
14248                        pw.print(" (high-end-gfx)");
14249                    }
14250                    pw.println();
14251                } else {
14252                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14253                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14254                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14255                    pw.print("tuning,");
14256                    pw.print(ActivityManager.staticGetMemoryClass());
14257                    pw.print(',');
14258                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14259                    pw.print(',');
14260                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14261                    if (ActivityManager.isLowRamDeviceStatic()) {
14262                        pw.print(",low-ram");
14263                    }
14264                    if (ActivityManager.isHighEndGfx()) {
14265                        pw.print(",high-end-gfx");
14266                    }
14267                    pw.println();
14268                }
14269            }
14270        }
14271    }
14272
14273    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14274            String name) {
14275        sb.append("  ");
14276        sb.append(ProcessList.makeOomAdjString(oomAdj));
14277        sb.append(' ');
14278        sb.append(ProcessList.makeProcStateString(procState));
14279        sb.append(' ');
14280        ProcessList.appendRamKb(sb, pss);
14281        sb.append(" kB: ");
14282        sb.append(name);
14283    }
14284
14285    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14286        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14287        sb.append(" (");
14288        sb.append(mi.pid);
14289        sb.append(") ");
14290        sb.append(mi.adjType);
14291        sb.append('\n');
14292        if (mi.adjReason != null) {
14293            sb.append("                      ");
14294            sb.append(mi.adjReason);
14295            sb.append('\n');
14296        }
14297    }
14298
14299    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14300        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14301        for (int i=0, N=memInfos.size(); i<N; i++) {
14302            ProcessMemInfo mi = memInfos.get(i);
14303            infoMap.put(mi.pid, mi);
14304        }
14305        updateCpuStatsNow();
14306        synchronized (mProcessCpuTracker) {
14307            final int N = mProcessCpuTracker.countStats();
14308            for (int i=0; i<N; i++) {
14309                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14310                if (st.vsize > 0) {
14311                    long pss = Debug.getPss(st.pid, null);
14312                    if (pss > 0) {
14313                        if (infoMap.indexOfKey(st.pid) < 0) {
14314                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14315                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14316                            mi.pss = pss;
14317                            memInfos.add(mi);
14318                        }
14319                    }
14320                }
14321            }
14322        }
14323
14324        long totalPss = 0;
14325        for (int i=0, N=memInfos.size(); i<N; i++) {
14326            ProcessMemInfo mi = memInfos.get(i);
14327            if (mi.pss == 0) {
14328                mi.pss = Debug.getPss(mi.pid, null);
14329            }
14330            totalPss += mi.pss;
14331        }
14332        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14333            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14334                if (lhs.oomAdj != rhs.oomAdj) {
14335                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14336                }
14337                if (lhs.pss != rhs.pss) {
14338                    return lhs.pss < rhs.pss ? 1 : -1;
14339                }
14340                return 0;
14341            }
14342        });
14343
14344        StringBuilder tag = new StringBuilder(128);
14345        StringBuilder stack = new StringBuilder(128);
14346        tag.append("Low on memory -- ");
14347        appendMemBucket(tag, totalPss, "total", false);
14348        appendMemBucket(stack, totalPss, "total", true);
14349
14350        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14351        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14352        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14353
14354        boolean firstLine = true;
14355        int lastOomAdj = Integer.MIN_VALUE;
14356        long extraNativeRam = 0;
14357        long cachedPss = 0;
14358        for (int i=0, N=memInfos.size(); i<N; i++) {
14359            ProcessMemInfo mi = memInfos.get(i);
14360
14361            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14362                cachedPss += mi.pss;
14363            }
14364
14365            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14366                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14367                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14368                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14369                if (lastOomAdj != mi.oomAdj) {
14370                    lastOomAdj = mi.oomAdj;
14371                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14372                        tag.append(" / ");
14373                    }
14374                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14375                        if (firstLine) {
14376                            stack.append(":");
14377                            firstLine = false;
14378                        }
14379                        stack.append("\n\t at ");
14380                    } else {
14381                        stack.append("$");
14382                    }
14383                } else {
14384                    tag.append(" ");
14385                    stack.append("$");
14386                }
14387                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14388                    appendMemBucket(tag, mi.pss, mi.name, false);
14389                }
14390                appendMemBucket(stack, mi.pss, mi.name, true);
14391                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14392                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14393                    stack.append("(");
14394                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14395                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14396                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14397                            stack.append(":");
14398                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14399                        }
14400                    }
14401                    stack.append(")");
14402                }
14403            }
14404
14405            appendMemInfo(fullNativeBuilder, mi);
14406            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14407                // The short form only has native processes that are >= 1MB.
14408                if (mi.pss >= 1000) {
14409                    appendMemInfo(shortNativeBuilder, mi);
14410                } else {
14411                    extraNativeRam += mi.pss;
14412                }
14413            } else {
14414                // Short form has all other details, but if we have collected RAM
14415                // from smaller native processes let's dump a summary of that.
14416                if (extraNativeRam > 0) {
14417                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14418                            -1, extraNativeRam, "(Other native)");
14419                    shortNativeBuilder.append('\n');
14420                    extraNativeRam = 0;
14421                }
14422                appendMemInfo(fullJavaBuilder, mi);
14423            }
14424        }
14425
14426        fullJavaBuilder.append("           ");
14427        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14428        fullJavaBuilder.append(" kB: TOTAL\n");
14429
14430        MemInfoReader memInfo = new MemInfoReader();
14431        memInfo.readMemInfo();
14432        final long[] infos = memInfo.getRawInfo();
14433
14434        StringBuilder memInfoBuilder = new StringBuilder(1024);
14435        Debug.getMemInfo(infos);
14436        memInfoBuilder.append("  MemInfo: ");
14437        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14438        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14439        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14440        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14441        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14442        memInfoBuilder.append("           ");
14443        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14444        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14445        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14446        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14447        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14448            memInfoBuilder.append("  ZRAM: ");
14449            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14450            memInfoBuilder.append(" kB RAM, ");
14451            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14452            memInfoBuilder.append(" kB swap total, ");
14453            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14454            memInfoBuilder.append(" kB swap free\n");
14455        }
14456        final long[] ksm = getKsmInfo();
14457        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14458                || ksm[KSM_VOLATILE] != 0) {
14459            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14460            memInfoBuilder.append(" kB saved from shared ");
14461            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14462            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14463            memInfoBuilder.append(" kB unshared; ");
14464            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14465        }
14466        memInfoBuilder.append("  Free RAM: ");
14467        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14468                + memInfo.getFreeSizeKb());
14469        memInfoBuilder.append(" kB\n");
14470        memInfoBuilder.append("  Used RAM: ");
14471        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14472        memInfoBuilder.append(" kB\n");
14473        memInfoBuilder.append("  Lost RAM: ");
14474        memInfoBuilder.append(memInfo.getTotalSizeKb()
14475                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14476                - memInfo.getKernelUsedSizeKb());
14477        memInfoBuilder.append(" kB\n");
14478        Slog.i(TAG, "Low on memory:");
14479        Slog.i(TAG, shortNativeBuilder.toString());
14480        Slog.i(TAG, fullJavaBuilder.toString());
14481        Slog.i(TAG, memInfoBuilder.toString());
14482
14483        StringBuilder dropBuilder = new StringBuilder(1024);
14484        /*
14485        StringWriter oomSw = new StringWriter();
14486        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14487        StringWriter catSw = new StringWriter();
14488        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14489        String[] emptyArgs = new String[] { };
14490        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14491        oomPw.flush();
14492        String oomString = oomSw.toString();
14493        */
14494        dropBuilder.append("Low on memory:");
14495        dropBuilder.append(stack);
14496        dropBuilder.append('\n');
14497        dropBuilder.append(fullNativeBuilder);
14498        dropBuilder.append(fullJavaBuilder);
14499        dropBuilder.append('\n');
14500        dropBuilder.append(memInfoBuilder);
14501        dropBuilder.append('\n');
14502        /*
14503        dropBuilder.append(oomString);
14504        dropBuilder.append('\n');
14505        */
14506        StringWriter catSw = new StringWriter();
14507        synchronized (ActivityManagerService.this) {
14508            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14509            String[] emptyArgs = new String[] { };
14510            catPw.println();
14511            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14512            catPw.println();
14513            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14514                    false, false, null);
14515            catPw.println();
14516            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14517            catPw.flush();
14518        }
14519        dropBuilder.append(catSw.toString());
14520        addErrorToDropBox("lowmem", null, "system_server", null,
14521                null, tag.toString(), dropBuilder.toString(), null, null);
14522        //Slog.i(TAG, "Sent to dropbox:");
14523        //Slog.i(TAG, dropBuilder.toString());
14524        synchronized (ActivityManagerService.this) {
14525            long now = SystemClock.uptimeMillis();
14526            if (mLastMemUsageReportTime < now) {
14527                mLastMemUsageReportTime = now;
14528            }
14529        }
14530    }
14531
14532    /**
14533     * Searches array of arguments for the specified string
14534     * @param args array of argument strings
14535     * @param value value to search for
14536     * @return true if the value is contained in the array
14537     */
14538    private static boolean scanArgs(String[] args, String value) {
14539        if (args != null) {
14540            for (String arg : args) {
14541                if (value.equals(arg)) {
14542                    return true;
14543                }
14544            }
14545        }
14546        return false;
14547    }
14548
14549    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14550            ContentProviderRecord cpr, boolean always) {
14551        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14552
14553        if (!inLaunching || always) {
14554            synchronized (cpr) {
14555                cpr.launchingApp = null;
14556                cpr.notifyAll();
14557            }
14558            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14559            String names[] = cpr.info.authority.split(";");
14560            for (int j = 0; j < names.length; j++) {
14561                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14562            }
14563        }
14564
14565        for (int i=0; i<cpr.connections.size(); i++) {
14566            ContentProviderConnection conn = cpr.connections.get(i);
14567            if (conn.waiting) {
14568                // If this connection is waiting for the provider, then we don't
14569                // need to mess with its process unless we are always removing
14570                // or for some reason the provider is not currently launching.
14571                if (inLaunching && !always) {
14572                    continue;
14573                }
14574            }
14575            ProcessRecord capp = conn.client;
14576            conn.dead = true;
14577            if (conn.stableCount > 0) {
14578                if (!capp.persistent && capp.thread != null
14579                        && capp.pid != 0
14580                        && capp.pid != MY_PID) {
14581                    capp.kill("depends on provider "
14582                            + cpr.name.flattenToShortString()
14583                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14584                }
14585            } else if (capp.thread != null && conn.provider.provider != null) {
14586                try {
14587                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14588                } catch (RemoteException e) {
14589                }
14590                // In the protocol here, we don't expect the client to correctly
14591                // clean up this connection, we'll just remove it.
14592                cpr.connections.remove(i);
14593                conn.client.conProviders.remove(conn);
14594            }
14595        }
14596
14597        if (inLaunching && always) {
14598            mLaunchingProviders.remove(cpr);
14599        }
14600        return inLaunching;
14601    }
14602
14603    /**
14604     * Main code for cleaning up a process when it has gone away.  This is
14605     * called both as a result of the process dying, or directly when stopping
14606     * a process when running in single process mode.
14607     *
14608     * @return Returns true if the given process has been restarted, so the
14609     * app that was passed in must remain on the process lists.
14610     */
14611    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14612            boolean restarting, boolean allowRestart, int index) {
14613        if (index >= 0) {
14614            removeLruProcessLocked(app);
14615            ProcessList.remove(app.pid);
14616        }
14617
14618        mProcessesToGc.remove(app);
14619        mPendingPssProcesses.remove(app);
14620
14621        // Dismiss any open dialogs.
14622        if (app.crashDialog != null && !app.forceCrashReport) {
14623            app.crashDialog.dismiss();
14624            app.crashDialog = null;
14625        }
14626        if (app.anrDialog != null) {
14627            app.anrDialog.dismiss();
14628            app.anrDialog = null;
14629        }
14630        if (app.waitDialog != null) {
14631            app.waitDialog.dismiss();
14632            app.waitDialog = null;
14633        }
14634
14635        app.crashing = false;
14636        app.notResponding = false;
14637
14638        app.resetPackageList(mProcessStats);
14639        app.unlinkDeathRecipient();
14640        app.makeInactive(mProcessStats);
14641        app.waitingToKill = null;
14642        app.forcingToForeground = null;
14643        updateProcessForegroundLocked(app, false, false);
14644        app.foregroundActivities = false;
14645        app.hasShownUi = false;
14646        app.treatLikeActivity = false;
14647        app.hasAboveClient = false;
14648        app.hasClientActivities = false;
14649
14650        mServices.killServicesLocked(app, allowRestart);
14651
14652        boolean restart = false;
14653
14654        // Remove published content providers.
14655        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14656            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14657            final boolean always = app.bad || !allowRestart;
14658            if (removeDyingProviderLocked(app, cpr, always) || always) {
14659                // We left the provider in the launching list, need to
14660                // restart it.
14661                restart = true;
14662            }
14663
14664            cpr.provider = null;
14665            cpr.proc = null;
14666        }
14667        app.pubProviders.clear();
14668
14669        // Take care of any launching providers waiting for this process.
14670        if (checkAppInLaunchingProvidersLocked(app, false)) {
14671            restart = true;
14672        }
14673
14674        // Unregister from connected content providers.
14675        if (!app.conProviders.isEmpty()) {
14676            for (int i=0; i<app.conProviders.size(); i++) {
14677                ContentProviderConnection conn = app.conProviders.get(i);
14678                conn.provider.connections.remove(conn);
14679            }
14680            app.conProviders.clear();
14681        }
14682
14683        // At this point there may be remaining entries in mLaunchingProviders
14684        // where we were the only one waiting, so they are no longer of use.
14685        // Look for these and clean up if found.
14686        // XXX Commented out for now.  Trying to figure out a way to reproduce
14687        // the actual situation to identify what is actually going on.
14688        if (false) {
14689            for (int i=0; i<mLaunchingProviders.size(); i++) {
14690                ContentProviderRecord cpr = (ContentProviderRecord)
14691                        mLaunchingProviders.get(i);
14692                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14693                    synchronized (cpr) {
14694                        cpr.launchingApp = null;
14695                        cpr.notifyAll();
14696                    }
14697                }
14698            }
14699        }
14700
14701        skipCurrentReceiverLocked(app);
14702
14703        // Unregister any receivers.
14704        for (int i=app.receivers.size()-1; i>=0; i--) {
14705            removeReceiverLocked(app.receivers.valueAt(i));
14706        }
14707        app.receivers.clear();
14708
14709        // If the app is undergoing backup, tell the backup manager about it
14710        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14711            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14712                    + mBackupTarget.appInfo + " died during backup");
14713            try {
14714                IBackupManager bm = IBackupManager.Stub.asInterface(
14715                        ServiceManager.getService(Context.BACKUP_SERVICE));
14716                bm.agentDisconnected(app.info.packageName);
14717            } catch (RemoteException e) {
14718                // can't happen; backup manager is local
14719            }
14720        }
14721
14722        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14723            ProcessChangeItem item = mPendingProcessChanges.get(i);
14724            if (item.pid == app.pid) {
14725                mPendingProcessChanges.remove(i);
14726                mAvailProcessChanges.add(item);
14727            }
14728        }
14729        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14730
14731        // If the caller is restarting this app, then leave it in its
14732        // current lists and let the caller take care of it.
14733        if (restarting) {
14734            return false;
14735        }
14736
14737        if (!app.persistent || app.isolated) {
14738            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14739                    "Removing non-persistent process during cleanup: " + app);
14740            mProcessNames.remove(app.processName, app.uid);
14741            mIsolatedProcesses.remove(app.uid);
14742            if (mHeavyWeightProcess == app) {
14743                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14744                        mHeavyWeightProcess.userId, 0));
14745                mHeavyWeightProcess = null;
14746            }
14747        } else if (!app.removed) {
14748            // This app is persistent, so we need to keep its record around.
14749            // If it is not already on the pending app list, add it there
14750            // and start a new process for it.
14751            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14752                mPersistentStartingProcesses.add(app);
14753                restart = true;
14754            }
14755        }
14756        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14757                "Clean-up removing on hold: " + app);
14758        mProcessesOnHold.remove(app);
14759
14760        if (app == mHomeProcess) {
14761            mHomeProcess = null;
14762        }
14763        if (app == mPreviousProcess) {
14764            mPreviousProcess = null;
14765        }
14766
14767        if (restart && !app.isolated) {
14768            // We have components that still need to be running in the
14769            // process, so re-launch it.
14770            if (index < 0) {
14771                ProcessList.remove(app.pid);
14772            }
14773            mProcessNames.put(app.processName, app.uid, app);
14774            startProcessLocked(app, "restart", app.processName);
14775            return true;
14776        } else if (app.pid > 0 && app.pid != MY_PID) {
14777            // Goodbye!
14778            boolean removed;
14779            synchronized (mPidsSelfLocked) {
14780                mPidsSelfLocked.remove(app.pid);
14781                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14782            }
14783            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14784            if (app.isolated) {
14785                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14786            }
14787            app.setPid(0);
14788        }
14789        return false;
14790    }
14791
14792    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14793        // Look through the content providers we are waiting to have launched,
14794        // and if any run in this process then either schedule a restart of
14795        // the process or kill the client waiting for it if this process has
14796        // gone bad.
14797        int NL = mLaunchingProviders.size();
14798        boolean restart = false;
14799        for (int i=0; i<NL; i++) {
14800            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14801            if (cpr.launchingApp == app) {
14802                if (!alwaysBad && !app.bad) {
14803                    restart = true;
14804                } else {
14805                    removeDyingProviderLocked(app, cpr, true);
14806                    // cpr should have been removed from mLaunchingProviders
14807                    NL = mLaunchingProviders.size();
14808                    i--;
14809                }
14810            }
14811        }
14812        return restart;
14813    }
14814
14815    // =========================================================
14816    // SERVICES
14817    // =========================================================
14818
14819    @Override
14820    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14821            int flags) {
14822        enforceNotIsolatedCaller("getServices");
14823        synchronized (this) {
14824            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14825        }
14826    }
14827
14828    @Override
14829    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14830        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14831        synchronized (this) {
14832            return mServices.getRunningServiceControlPanelLocked(name);
14833        }
14834    }
14835
14836    @Override
14837    public ComponentName startService(IApplicationThread caller, Intent service,
14838            String resolvedType, int userId) {
14839        enforceNotIsolatedCaller("startService");
14840        // Refuse possible leaked file descriptors
14841        if (service != null && service.hasFileDescriptors() == true) {
14842            throw new IllegalArgumentException("File descriptors passed in Intent");
14843        }
14844
14845        if (DEBUG_SERVICE)
14846            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14847        synchronized(this) {
14848            final int callingPid = Binder.getCallingPid();
14849            final int callingUid = Binder.getCallingUid();
14850            final long origId = Binder.clearCallingIdentity();
14851            ComponentName res = mServices.startServiceLocked(caller, service,
14852                    resolvedType, callingPid, callingUid, userId);
14853            Binder.restoreCallingIdentity(origId);
14854            return res;
14855        }
14856    }
14857
14858    ComponentName startServiceInPackage(int uid,
14859            Intent service, String resolvedType, int userId) {
14860        synchronized(this) {
14861            if (DEBUG_SERVICE)
14862                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14863            final long origId = Binder.clearCallingIdentity();
14864            ComponentName res = mServices.startServiceLocked(null, service,
14865                    resolvedType, -1, uid, userId);
14866            Binder.restoreCallingIdentity(origId);
14867            return res;
14868        }
14869    }
14870
14871    @Override
14872    public int stopService(IApplicationThread caller, Intent service,
14873            String resolvedType, int userId) {
14874        enforceNotIsolatedCaller("stopService");
14875        // Refuse possible leaked file descriptors
14876        if (service != null && service.hasFileDescriptors() == true) {
14877            throw new IllegalArgumentException("File descriptors passed in Intent");
14878        }
14879
14880        synchronized(this) {
14881            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14882        }
14883    }
14884
14885    @Override
14886    public IBinder peekService(Intent service, String resolvedType) {
14887        enforceNotIsolatedCaller("peekService");
14888        // Refuse possible leaked file descriptors
14889        if (service != null && service.hasFileDescriptors() == true) {
14890            throw new IllegalArgumentException("File descriptors passed in Intent");
14891        }
14892        synchronized(this) {
14893            return mServices.peekServiceLocked(service, resolvedType);
14894        }
14895    }
14896
14897    @Override
14898    public boolean stopServiceToken(ComponentName className, IBinder token,
14899            int startId) {
14900        synchronized(this) {
14901            return mServices.stopServiceTokenLocked(className, token, startId);
14902        }
14903    }
14904
14905    @Override
14906    public void setServiceForeground(ComponentName className, IBinder token,
14907            int id, Notification notification, boolean removeNotification) {
14908        synchronized(this) {
14909            mServices.setServiceForegroundLocked(className, token, id, notification,
14910                    removeNotification);
14911        }
14912    }
14913
14914    @Override
14915    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14916            boolean requireFull, String name, String callerPackage) {
14917        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14918                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14919    }
14920
14921    int unsafeConvertIncomingUser(int userId) {
14922        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14923                ? mCurrentUserId : userId;
14924    }
14925
14926    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14927            int allowMode, String name, String callerPackage) {
14928        final int callingUserId = UserHandle.getUserId(callingUid);
14929        if (callingUserId == userId) {
14930            return userId;
14931        }
14932
14933        // Note that we may be accessing mCurrentUserId outside of a lock...
14934        // shouldn't be a big deal, if this is being called outside
14935        // of a locked context there is intrinsically a race with
14936        // the value the caller will receive and someone else changing it.
14937        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14938        // we will switch to the calling user if access to the current user fails.
14939        int targetUserId = unsafeConvertIncomingUser(userId);
14940
14941        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14942            final boolean allow;
14943            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14944                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14945                // If the caller has this permission, they always pass go.  And collect $200.
14946                allow = true;
14947            } else if (allowMode == ALLOW_FULL_ONLY) {
14948                // We require full access, sucks to be you.
14949                allow = false;
14950            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14951                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14952                // If the caller does not have either permission, they are always doomed.
14953                allow = false;
14954            } else if (allowMode == ALLOW_NON_FULL) {
14955                // We are blanket allowing non-full access, you lucky caller!
14956                allow = true;
14957            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14958                // We may or may not allow this depending on whether the two users are
14959                // in the same profile.
14960                synchronized (mUserProfileGroupIdsSelfLocked) {
14961                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14962                            UserInfo.NO_PROFILE_GROUP_ID);
14963                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14964                            UserInfo.NO_PROFILE_GROUP_ID);
14965                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14966                            && callingProfile == targetProfile;
14967                }
14968            } else {
14969                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14970            }
14971            if (!allow) {
14972                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14973                    // In this case, they would like to just execute as their
14974                    // owner user instead of failing.
14975                    targetUserId = callingUserId;
14976                } else {
14977                    StringBuilder builder = new StringBuilder(128);
14978                    builder.append("Permission Denial: ");
14979                    builder.append(name);
14980                    if (callerPackage != null) {
14981                        builder.append(" from ");
14982                        builder.append(callerPackage);
14983                    }
14984                    builder.append(" asks to run as user ");
14985                    builder.append(userId);
14986                    builder.append(" but is calling from user ");
14987                    builder.append(UserHandle.getUserId(callingUid));
14988                    builder.append("; this requires ");
14989                    builder.append(INTERACT_ACROSS_USERS_FULL);
14990                    if (allowMode != ALLOW_FULL_ONLY) {
14991                        builder.append(" or ");
14992                        builder.append(INTERACT_ACROSS_USERS);
14993                    }
14994                    String msg = builder.toString();
14995                    Slog.w(TAG, msg);
14996                    throw new SecurityException(msg);
14997                }
14998            }
14999        }
15000        if (!allowAll && targetUserId < 0) {
15001            throw new IllegalArgumentException(
15002                    "Call does not support special user #" + targetUserId);
15003        }
15004        // Check shell permission
15005        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15006            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15007                    targetUserId)) {
15008                throw new SecurityException("Shell does not have permission to access user "
15009                        + targetUserId + "\n " + Debug.getCallers(3));
15010            }
15011        }
15012        return targetUserId;
15013    }
15014
15015    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15016            String className, int flags) {
15017        boolean result = false;
15018        // For apps that don't have pre-defined UIDs, check for permission
15019        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15020            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15021                if (ActivityManager.checkUidPermission(
15022                        INTERACT_ACROSS_USERS,
15023                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15024                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15025                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15026                            + " requests FLAG_SINGLE_USER, but app does not hold "
15027                            + INTERACT_ACROSS_USERS;
15028                    Slog.w(TAG, msg);
15029                    throw new SecurityException(msg);
15030                }
15031                // Permission passed
15032                result = true;
15033            }
15034        } else if ("system".equals(componentProcessName)) {
15035            result = true;
15036        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15037            // Phone app and persistent apps are allowed to export singleuser providers.
15038            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15039                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15040        }
15041        if (DEBUG_MU) {
15042            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15043                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15044        }
15045        return result;
15046    }
15047
15048    /**
15049     * Checks to see if the caller is in the same app as the singleton
15050     * component, or the component is in a special app. It allows special apps
15051     * to export singleton components but prevents exporting singleton
15052     * components for regular apps.
15053     */
15054    boolean isValidSingletonCall(int callingUid, int componentUid) {
15055        int componentAppId = UserHandle.getAppId(componentUid);
15056        return UserHandle.isSameApp(callingUid, componentUid)
15057                || componentAppId == Process.SYSTEM_UID
15058                || componentAppId == Process.PHONE_UID
15059                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15060                        == PackageManager.PERMISSION_GRANTED;
15061    }
15062
15063    public int bindService(IApplicationThread caller, IBinder token,
15064            Intent service, String resolvedType,
15065            IServiceConnection connection, int flags, int userId) {
15066        enforceNotIsolatedCaller("bindService");
15067
15068        // Refuse possible leaked file descriptors
15069        if (service != null && service.hasFileDescriptors() == true) {
15070            throw new IllegalArgumentException("File descriptors passed in Intent");
15071        }
15072
15073        synchronized(this) {
15074            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15075                    connection, flags, userId);
15076        }
15077    }
15078
15079    public boolean unbindService(IServiceConnection connection) {
15080        synchronized (this) {
15081            return mServices.unbindServiceLocked(connection);
15082        }
15083    }
15084
15085    public void publishService(IBinder token, Intent intent, IBinder service) {
15086        // Refuse possible leaked file descriptors
15087        if (intent != null && intent.hasFileDescriptors() == true) {
15088            throw new IllegalArgumentException("File descriptors passed in Intent");
15089        }
15090
15091        synchronized(this) {
15092            if (!(token instanceof ServiceRecord)) {
15093                throw new IllegalArgumentException("Invalid service token");
15094            }
15095            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15096        }
15097    }
15098
15099    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15100        // Refuse possible leaked file descriptors
15101        if (intent != null && intent.hasFileDescriptors() == true) {
15102            throw new IllegalArgumentException("File descriptors passed in Intent");
15103        }
15104
15105        synchronized(this) {
15106            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15107        }
15108    }
15109
15110    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15111        synchronized(this) {
15112            if (!(token instanceof ServiceRecord)) {
15113                throw new IllegalArgumentException("Invalid service token");
15114            }
15115            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15116        }
15117    }
15118
15119    // =========================================================
15120    // BACKUP AND RESTORE
15121    // =========================================================
15122
15123    // Cause the target app to be launched if necessary and its backup agent
15124    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15125    // activity manager to announce its creation.
15126    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15127        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15128        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15129
15130        synchronized(this) {
15131            // !!! TODO: currently no check here that we're already bound
15132            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15133            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15134            synchronized (stats) {
15135                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15136            }
15137
15138            // Backup agent is now in use, its package can't be stopped.
15139            try {
15140                AppGlobals.getPackageManager().setPackageStoppedState(
15141                        app.packageName, false, UserHandle.getUserId(app.uid));
15142            } catch (RemoteException e) {
15143            } catch (IllegalArgumentException e) {
15144                Slog.w(TAG, "Failed trying to unstop package "
15145                        + app.packageName + ": " + e);
15146            }
15147
15148            BackupRecord r = new BackupRecord(ss, app, backupMode);
15149            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15150                    ? new ComponentName(app.packageName, app.backupAgentName)
15151                    : new ComponentName("android", "FullBackupAgent");
15152            // startProcessLocked() returns existing proc's record if it's already running
15153            ProcessRecord proc = startProcessLocked(app.processName, app,
15154                    false, 0, "backup", hostingName, false, false, false);
15155            if (proc == null) {
15156                Slog.e(TAG, "Unable to start backup agent process " + r);
15157                return false;
15158            }
15159
15160            r.app = proc;
15161            mBackupTarget = r;
15162            mBackupAppName = app.packageName;
15163
15164            // Try not to kill the process during backup
15165            updateOomAdjLocked(proc);
15166
15167            // If the process is already attached, schedule the creation of the backup agent now.
15168            // If it is not yet live, this will be done when it attaches to the framework.
15169            if (proc.thread != null) {
15170                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15171                try {
15172                    proc.thread.scheduleCreateBackupAgent(app,
15173                            compatibilityInfoForPackageLocked(app), backupMode);
15174                } catch (RemoteException e) {
15175                    // Will time out on the backup manager side
15176                }
15177            } else {
15178                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15179            }
15180            // Invariants: at this point, the target app process exists and the application
15181            // is either already running or in the process of coming up.  mBackupTarget and
15182            // mBackupAppName describe the app, so that when it binds back to the AM we
15183            // know that it's scheduled for a backup-agent operation.
15184        }
15185
15186        return true;
15187    }
15188
15189    @Override
15190    public void clearPendingBackup() {
15191        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15192        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15193
15194        synchronized (this) {
15195            mBackupTarget = null;
15196            mBackupAppName = null;
15197        }
15198    }
15199
15200    // A backup agent has just come up
15201    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15202        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15203                + " = " + agent);
15204
15205        synchronized(this) {
15206            if (!agentPackageName.equals(mBackupAppName)) {
15207                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15208                return;
15209            }
15210        }
15211
15212        long oldIdent = Binder.clearCallingIdentity();
15213        try {
15214            IBackupManager bm = IBackupManager.Stub.asInterface(
15215                    ServiceManager.getService(Context.BACKUP_SERVICE));
15216            bm.agentConnected(agentPackageName, agent);
15217        } catch (RemoteException e) {
15218            // can't happen; the backup manager service is local
15219        } catch (Exception e) {
15220            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15221            e.printStackTrace();
15222        } finally {
15223            Binder.restoreCallingIdentity(oldIdent);
15224        }
15225    }
15226
15227    // done with this agent
15228    public void unbindBackupAgent(ApplicationInfo appInfo) {
15229        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15230        if (appInfo == null) {
15231            Slog.w(TAG, "unbind backup agent for null app");
15232            return;
15233        }
15234
15235        synchronized(this) {
15236            try {
15237                if (mBackupAppName == null) {
15238                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15239                    return;
15240                }
15241
15242                if (!mBackupAppName.equals(appInfo.packageName)) {
15243                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15244                    return;
15245                }
15246
15247                // Not backing this app up any more; reset its OOM adjustment
15248                final ProcessRecord proc = mBackupTarget.app;
15249                updateOomAdjLocked(proc);
15250
15251                // If the app crashed during backup, 'thread' will be null here
15252                if (proc.thread != null) {
15253                    try {
15254                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15255                                compatibilityInfoForPackageLocked(appInfo));
15256                    } catch (Exception e) {
15257                        Slog.e(TAG, "Exception when unbinding backup agent:");
15258                        e.printStackTrace();
15259                    }
15260                }
15261            } finally {
15262                mBackupTarget = null;
15263                mBackupAppName = null;
15264            }
15265        }
15266    }
15267    // =========================================================
15268    // BROADCASTS
15269    // =========================================================
15270
15271    private final List getStickiesLocked(String action, IntentFilter filter,
15272            List cur, int userId) {
15273        final ContentResolver resolver = mContext.getContentResolver();
15274        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15275        if (stickies == null) {
15276            return cur;
15277        }
15278        final ArrayList<Intent> list = stickies.get(action);
15279        if (list == null) {
15280            return cur;
15281        }
15282        int N = list.size();
15283        for (int i=0; i<N; i++) {
15284            Intent intent = list.get(i);
15285            if (filter.match(resolver, intent, true, TAG) >= 0) {
15286                if (cur == null) {
15287                    cur = new ArrayList<Intent>();
15288                }
15289                cur.add(intent);
15290            }
15291        }
15292        return cur;
15293    }
15294
15295    boolean isPendingBroadcastProcessLocked(int pid) {
15296        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15297                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15298    }
15299
15300    void skipPendingBroadcastLocked(int pid) {
15301            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15302            for (BroadcastQueue queue : mBroadcastQueues) {
15303                queue.skipPendingBroadcastLocked(pid);
15304            }
15305    }
15306
15307    // The app just attached; send any pending broadcasts that it should receive
15308    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15309        boolean didSomething = false;
15310        for (BroadcastQueue queue : mBroadcastQueues) {
15311            didSomething |= queue.sendPendingBroadcastsLocked(app);
15312        }
15313        return didSomething;
15314    }
15315
15316    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15317            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15318        enforceNotIsolatedCaller("registerReceiver");
15319        int callingUid;
15320        int callingPid;
15321        synchronized(this) {
15322            ProcessRecord callerApp = null;
15323            if (caller != null) {
15324                callerApp = getRecordForAppLocked(caller);
15325                if (callerApp == null) {
15326                    throw new SecurityException(
15327                            "Unable to find app for caller " + caller
15328                            + " (pid=" + Binder.getCallingPid()
15329                            + ") when registering receiver " + receiver);
15330                }
15331                if (callerApp.info.uid != Process.SYSTEM_UID &&
15332                        !callerApp.pkgList.containsKey(callerPackage) &&
15333                        !"android".equals(callerPackage)) {
15334                    throw new SecurityException("Given caller package " + callerPackage
15335                            + " is not running in process " + callerApp);
15336                }
15337                callingUid = callerApp.info.uid;
15338                callingPid = callerApp.pid;
15339            } else {
15340                callerPackage = null;
15341                callingUid = Binder.getCallingUid();
15342                callingPid = Binder.getCallingPid();
15343            }
15344
15345            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15346                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15347
15348            List allSticky = null;
15349
15350            // Look for any matching sticky broadcasts...
15351            Iterator actions = filter.actionsIterator();
15352            if (actions != null) {
15353                while (actions.hasNext()) {
15354                    String action = (String)actions.next();
15355                    allSticky = getStickiesLocked(action, filter, allSticky,
15356                            UserHandle.USER_ALL);
15357                    allSticky = getStickiesLocked(action, filter, allSticky,
15358                            UserHandle.getUserId(callingUid));
15359                }
15360            } else {
15361                allSticky = getStickiesLocked(null, filter, allSticky,
15362                        UserHandle.USER_ALL);
15363                allSticky = getStickiesLocked(null, filter, allSticky,
15364                        UserHandle.getUserId(callingUid));
15365            }
15366
15367            // The first sticky in the list is returned directly back to
15368            // the client.
15369            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15370
15371            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15372                    + ": " + sticky);
15373
15374            if (receiver == null) {
15375                return sticky;
15376            }
15377
15378            ReceiverList rl
15379                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15380            if (rl == null) {
15381                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15382                        userId, receiver);
15383                if (rl.app != null) {
15384                    rl.app.receivers.add(rl);
15385                } else {
15386                    try {
15387                        receiver.asBinder().linkToDeath(rl, 0);
15388                    } catch (RemoteException e) {
15389                        return sticky;
15390                    }
15391                    rl.linkedToDeath = true;
15392                }
15393                mRegisteredReceivers.put(receiver.asBinder(), rl);
15394            } else if (rl.uid != callingUid) {
15395                throw new IllegalArgumentException(
15396                        "Receiver requested to register for uid " + callingUid
15397                        + " was previously registered for uid " + rl.uid);
15398            } else if (rl.pid != callingPid) {
15399                throw new IllegalArgumentException(
15400                        "Receiver requested to register for pid " + callingPid
15401                        + " was previously registered for pid " + rl.pid);
15402            } else if (rl.userId != userId) {
15403                throw new IllegalArgumentException(
15404                        "Receiver requested to register for user " + userId
15405                        + " was previously registered for user " + rl.userId);
15406            }
15407            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15408                    permission, callingUid, userId);
15409            rl.add(bf);
15410            if (!bf.debugCheck()) {
15411                Slog.w(TAG, "==> For Dynamic broadast");
15412            }
15413            mReceiverResolver.addFilter(bf);
15414
15415            // Enqueue broadcasts for all existing stickies that match
15416            // this filter.
15417            if (allSticky != null) {
15418                ArrayList receivers = new ArrayList();
15419                receivers.add(bf);
15420
15421                int N = allSticky.size();
15422                for (int i=0; i<N; i++) {
15423                    Intent intent = (Intent)allSticky.get(i);
15424                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15425                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15426                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15427                            null, null, false, true, true, -1);
15428                    queue.enqueueParallelBroadcastLocked(r);
15429                    queue.scheduleBroadcastsLocked();
15430                }
15431            }
15432
15433            return sticky;
15434        }
15435    }
15436
15437    public void unregisterReceiver(IIntentReceiver receiver) {
15438        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15439
15440        final long origId = Binder.clearCallingIdentity();
15441        try {
15442            boolean doTrim = false;
15443
15444            synchronized(this) {
15445                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15446                if (rl != null) {
15447                    if (rl.curBroadcast != null) {
15448                        BroadcastRecord r = rl.curBroadcast;
15449                        final boolean doNext = finishReceiverLocked(
15450                                receiver.asBinder(), r.resultCode, r.resultData,
15451                                r.resultExtras, r.resultAbort);
15452                        if (doNext) {
15453                            doTrim = true;
15454                            r.queue.processNextBroadcast(false);
15455                        }
15456                    }
15457
15458                    if (rl.app != null) {
15459                        rl.app.receivers.remove(rl);
15460                    }
15461                    removeReceiverLocked(rl);
15462                    if (rl.linkedToDeath) {
15463                        rl.linkedToDeath = false;
15464                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15465                    }
15466                }
15467            }
15468
15469            // If we actually concluded any broadcasts, we might now be able
15470            // to trim the recipients' apps from our working set
15471            if (doTrim) {
15472                trimApplications();
15473                return;
15474            }
15475
15476        } finally {
15477            Binder.restoreCallingIdentity(origId);
15478        }
15479    }
15480
15481    void removeReceiverLocked(ReceiverList rl) {
15482        mRegisteredReceivers.remove(rl.receiver.asBinder());
15483        int N = rl.size();
15484        for (int i=0; i<N; i++) {
15485            mReceiverResolver.removeFilter(rl.get(i));
15486        }
15487    }
15488
15489    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15490        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15491            ProcessRecord r = mLruProcesses.get(i);
15492            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15493                try {
15494                    r.thread.dispatchPackageBroadcast(cmd, packages);
15495                } catch (RemoteException ex) {
15496                }
15497            }
15498        }
15499    }
15500
15501    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15502            int callingUid, int[] users) {
15503        List<ResolveInfo> receivers = null;
15504        try {
15505            HashSet<ComponentName> singleUserReceivers = null;
15506            boolean scannedFirstReceivers = false;
15507            for (int user : users) {
15508                // Skip users that have Shell restrictions
15509                if (callingUid == Process.SHELL_UID
15510                        && getUserManagerLocked().hasUserRestriction(
15511                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15512                    continue;
15513                }
15514                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15515                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15516                if (user != 0 && newReceivers != null) {
15517                    // If this is not the primary user, we need to check for
15518                    // any receivers that should be filtered out.
15519                    for (int i=0; i<newReceivers.size(); i++) {
15520                        ResolveInfo ri = newReceivers.get(i);
15521                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15522                            newReceivers.remove(i);
15523                            i--;
15524                        }
15525                    }
15526                }
15527                if (newReceivers != null && newReceivers.size() == 0) {
15528                    newReceivers = null;
15529                }
15530                if (receivers == null) {
15531                    receivers = newReceivers;
15532                } else if (newReceivers != null) {
15533                    // We need to concatenate the additional receivers
15534                    // found with what we have do far.  This would be easy,
15535                    // but we also need to de-dup any receivers that are
15536                    // singleUser.
15537                    if (!scannedFirstReceivers) {
15538                        // Collect any single user receivers we had already retrieved.
15539                        scannedFirstReceivers = true;
15540                        for (int i=0; i<receivers.size(); i++) {
15541                            ResolveInfo ri = receivers.get(i);
15542                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15543                                ComponentName cn = new ComponentName(
15544                                        ri.activityInfo.packageName, ri.activityInfo.name);
15545                                if (singleUserReceivers == null) {
15546                                    singleUserReceivers = new HashSet<ComponentName>();
15547                                }
15548                                singleUserReceivers.add(cn);
15549                            }
15550                        }
15551                    }
15552                    // Add the new results to the existing results, tracking
15553                    // and de-dupping single user receivers.
15554                    for (int i=0; i<newReceivers.size(); i++) {
15555                        ResolveInfo ri = newReceivers.get(i);
15556                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15557                            ComponentName cn = new ComponentName(
15558                                    ri.activityInfo.packageName, ri.activityInfo.name);
15559                            if (singleUserReceivers == null) {
15560                                singleUserReceivers = new HashSet<ComponentName>();
15561                            }
15562                            if (!singleUserReceivers.contains(cn)) {
15563                                singleUserReceivers.add(cn);
15564                                receivers.add(ri);
15565                            }
15566                        } else {
15567                            receivers.add(ri);
15568                        }
15569                    }
15570                }
15571            }
15572        } catch (RemoteException ex) {
15573            // pm is in same process, this will never happen.
15574        }
15575        return receivers;
15576    }
15577
15578    private final int broadcastIntentLocked(ProcessRecord callerApp,
15579            String callerPackage, Intent intent, String resolvedType,
15580            IIntentReceiver resultTo, int resultCode, String resultData,
15581            Bundle map, String requiredPermission, int appOp,
15582            boolean ordered, boolean sticky, int callingPid, int callingUid,
15583            int userId) {
15584        intent = new Intent(intent);
15585
15586        // By default broadcasts do not go to stopped apps.
15587        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15588
15589        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15590            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15591            + " ordered=" + ordered + " userid=" + userId);
15592        if ((resultTo != null) && !ordered) {
15593            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15594        }
15595
15596        userId = handleIncomingUser(callingPid, callingUid, userId,
15597                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15598
15599        // Make sure that the user who is receiving this broadcast is started.
15600        // If not, we will just skip it.
15601
15602        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15603            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15604                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15605                Slog.w(TAG, "Skipping broadcast of " + intent
15606                        + ": user " + userId + " is stopped");
15607                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15608            }
15609        }
15610
15611        /*
15612         * Prevent non-system code (defined here to be non-persistent
15613         * processes) from sending protected broadcasts.
15614         */
15615        int callingAppId = UserHandle.getAppId(callingUid);
15616        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15617            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15618            || callingAppId == Process.NFC_UID || callingUid == 0) {
15619            // Always okay.
15620        } else if (callerApp == null || !callerApp.persistent) {
15621            try {
15622                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15623                        intent.getAction())) {
15624                    String msg = "Permission Denial: not allowed to send broadcast "
15625                            + intent.getAction() + " from pid="
15626                            + callingPid + ", uid=" + callingUid;
15627                    Slog.w(TAG, msg);
15628                    throw new SecurityException(msg);
15629                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15630                    // Special case for compatibility: we don't want apps to send this,
15631                    // but historically it has not been protected and apps may be using it
15632                    // to poke their own app widget.  So, instead of making it protected,
15633                    // just limit it to the caller.
15634                    if (callerApp == null) {
15635                        String msg = "Permission Denial: not allowed to send broadcast "
15636                                + intent.getAction() + " from unknown caller.";
15637                        Slog.w(TAG, msg);
15638                        throw new SecurityException(msg);
15639                    } else if (intent.getComponent() != null) {
15640                        // They are good enough to send to an explicit component...  verify
15641                        // it is being sent to the calling app.
15642                        if (!intent.getComponent().getPackageName().equals(
15643                                callerApp.info.packageName)) {
15644                            String msg = "Permission Denial: not allowed to send broadcast "
15645                                    + intent.getAction() + " to "
15646                                    + intent.getComponent().getPackageName() + " from "
15647                                    + callerApp.info.packageName;
15648                            Slog.w(TAG, msg);
15649                            throw new SecurityException(msg);
15650                        }
15651                    } else {
15652                        // Limit broadcast to their own package.
15653                        intent.setPackage(callerApp.info.packageName);
15654                    }
15655                }
15656            } catch (RemoteException e) {
15657                Slog.w(TAG, "Remote exception", e);
15658                return ActivityManager.BROADCAST_SUCCESS;
15659            }
15660        }
15661
15662        final String action = intent.getAction();
15663        if (action != null) {
15664            switch (action) {
15665                case Intent.ACTION_UID_REMOVED:
15666                case Intent.ACTION_PACKAGE_REMOVED:
15667                case Intent.ACTION_PACKAGE_CHANGED:
15668                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15669                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15670                    // Handle special intents: if this broadcast is from the package
15671                    // manager about a package being removed, we need to remove all of
15672                    // its activities from the history stack.
15673                    if (checkComponentPermission(
15674                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15675                            callingPid, callingUid, -1, true)
15676                            != PackageManager.PERMISSION_GRANTED) {
15677                        String msg = "Permission Denial: " + intent.getAction()
15678                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15679                                + ", uid=" + callingUid + ")"
15680                                + " requires "
15681                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15682                        Slog.w(TAG, msg);
15683                        throw new SecurityException(msg);
15684                    }
15685                    switch (action) {
15686                        case Intent.ACTION_UID_REMOVED:
15687                            final Bundle intentExtras = intent.getExtras();
15688                            final int uid = intentExtras != null
15689                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15690                            if (uid >= 0) {
15691                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15692                                synchronized (bs) {
15693                                    bs.removeUidStatsLocked(uid);
15694                                }
15695                                mAppOpsService.uidRemoved(uid);
15696                            }
15697                            break;
15698                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15699                            // If resources are unavailable just force stop all those packages
15700                            // and flush the attribute cache as well.
15701                            String list[] =
15702                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15703                            if (list != null && list.length > 0) {
15704                                for (int i = 0; i < list.length; i++) {
15705                                    forceStopPackageLocked(list[i], -1, false, true, true,
15706                                            false, false, userId, "storage unmount");
15707                                }
15708                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15709                                sendPackageBroadcastLocked(
15710                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15711                                        userId);
15712                            }
15713                            break;
15714                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15715                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15716                            break;
15717                        case Intent.ACTION_PACKAGE_REMOVED:
15718                        case Intent.ACTION_PACKAGE_CHANGED:
15719                            Uri data = intent.getData();
15720                            String ssp;
15721                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15722                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15723                                boolean fullUninstall = removed &&
15724                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15725                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15726                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15727                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15728                                            false, true, true, false, fullUninstall, userId,
15729                                            removed ? "pkg removed" : "pkg changed");
15730                                }
15731                                if (removed) {
15732                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15733                                            new String[] {ssp}, userId);
15734                                    if (fullUninstall) {
15735                                        mAppOpsService.packageRemoved(
15736                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15737
15738                                        // Remove all permissions granted from/to this package
15739                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15740
15741                                        removeTasksByPackageNameLocked(ssp, userId);
15742                                    }
15743                                } else {
15744                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15745                                }
15746                            }
15747                            break;
15748                    }
15749                    break;
15750                case Intent.ACTION_PACKAGE_ADDED:
15751                    // Special case for adding a package: by default turn on compatibility mode.
15752                    Uri data = intent.getData();
15753                    String ssp;
15754                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15755                        final boolean replacing =
15756                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15757                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15758
15759                        if (replacing) {
15760                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15761                        }
15762                    }
15763                    break;
15764                case Intent.ACTION_TIMEZONE_CHANGED:
15765                    // If this is the time zone changed action, queue up a message that will reset
15766                    // the timezone of all currently running processes. This message will get
15767                    // queued up before the broadcast happens.
15768                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15769                    break;
15770                case Intent.ACTION_TIME_CHANGED:
15771                    // If the user set the time, let all running processes know.
15772                    final int is24Hour =
15773                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15774                                    : 0;
15775                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15776                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15777                    synchronized (stats) {
15778                        stats.noteCurrentTimeChangedLocked();
15779                    }
15780                    break;
15781                case Intent.ACTION_CLEAR_DNS_CACHE:
15782                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15783                    break;
15784                case Proxy.PROXY_CHANGE_ACTION:
15785                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15786                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15787                    break;
15788            }
15789        }
15790
15791        // Add to the sticky list if requested.
15792        if (sticky) {
15793            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15794                    callingPid, callingUid)
15795                    != PackageManager.PERMISSION_GRANTED) {
15796                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15797                        + callingPid + ", uid=" + callingUid
15798                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15799                Slog.w(TAG, msg);
15800                throw new SecurityException(msg);
15801            }
15802            if (requiredPermission != null) {
15803                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15804                        + " and enforce permission " + requiredPermission);
15805                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15806            }
15807            if (intent.getComponent() != null) {
15808                throw new SecurityException(
15809                        "Sticky broadcasts can't target a specific component");
15810            }
15811            // We use userId directly here, since the "all" target is maintained
15812            // as a separate set of sticky broadcasts.
15813            if (userId != UserHandle.USER_ALL) {
15814                // But first, if this is not a broadcast to all users, then
15815                // make sure it doesn't conflict with an existing broadcast to
15816                // all users.
15817                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15818                        UserHandle.USER_ALL);
15819                if (stickies != null) {
15820                    ArrayList<Intent> list = stickies.get(intent.getAction());
15821                    if (list != null) {
15822                        int N = list.size();
15823                        int i;
15824                        for (i=0; i<N; i++) {
15825                            if (intent.filterEquals(list.get(i))) {
15826                                throw new IllegalArgumentException(
15827                                        "Sticky broadcast " + intent + " for user "
15828                                        + userId + " conflicts with existing global broadcast");
15829                            }
15830                        }
15831                    }
15832                }
15833            }
15834            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15835            if (stickies == null) {
15836                stickies = new ArrayMap<String, ArrayList<Intent>>();
15837                mStickyBroadcasts.put(userId, stickies);
15838            }
15839            ArrayList<Intent> list = stickies.get(intent.getAction());
15840            if (list == null) {
15841                list = new ArrayList<Intent>();
15842                stickies.put(intent.getAction(), list);
15843            }
15844            int N = list.size();
15845            int i;
15846            for (i=0; i<N; i++) {
15847                if (intent.filterEquals(list.get(i))) {
15848                    // This sticky already exists, replace it.
15849                    list.set(i, new Intent(intent));
15850                    break;
15851                }
15852            }
15853            if (i >= N) {
15854                list.add(new Intent(intent));
15855            }
15856        }
15857
15858        int[] users;
15859        if (userId == UserHandle.USER_ALL) {
15860            // Caller wants broadcast to go to all started users.
15861            users = mStartedUserArray;
15862        } else {
15863            // Caller wants broadcast to go to one specific user.
15864            users = new int[] {userId};
15865        }
15866
15867        // Figure out who all will receive this broadcast.
15868        List receivers = null;
15869        List<BroadcastFilter> registeredReceivers = null;
15870        // Need to resolve the intent to interested receivers...
15871        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15872                 == 0) {
15873            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15874        }
15875        if (intent.getComponent() == null) {
15876            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15877                // Query one target user at a time, excluding shell-restricted users
15878                UserManagerService ums = getUserManagerLocked();
15879                for (int i = 0; i < users.length; i++) {
15880                    if (ums.hasUserRestriction(
15881                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15882                        continue;
15883                    }
15884                    List<BroadcastFilter> registeredReceiversForUser =
15885                            mReceiverResolver.queryIntent(intent,
15886                                    resolvedType, false, users[i]);
15887                    if (registeredReceivers == null) {
15888                        registeredReceivers = registeredReceiversForUser;
15889                    } else if (registeredReceiversForUser != null) {
15890                        registeredReceivers.addAll(registeredReceiversForUser);
15891                    }
15892                }
15893            } else {
15894                registeredReceivers = mReceiverResolver.queryIntent(intent,
15895                        resolvedType, false, userId);
15896            }
15897        }
15898
15899        final boolean replacePending =
15900                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15901
15902        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15903                + " replacePending=" + replacePending);
15904
15905        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15906        if (!ordered && NR > 0) {
15907            // If we are not serializing this broadcast, then send the
15908            // registered receivers separately so they don't wait for the
15909            // components to be launched.
15910            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15911            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15912                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15913                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15914                    ordered, sticky, false, userId);
15915            if (DEBUG_BROADCAST) Slog.v(
15916                    TAG, "Enqueueing parallel broadcast " + r);
15917            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15918            if (!replaced) {
15919                queue.enqueueParallelBroadcastLocked(r);
15920                queue.scheduleBroadcastsLocked();
15921            }
15922            registeredReceivers = null;
15923            NR = 0;
15924        }
15925
15926        // Merge into one list.
15927        int ir = 0;
15928        if (receivers != null) {
15929            // A special case for PACKAGE_ADDED: do not allow the package
15930            // being added to see this broadcast.  This prevents them from
15931            // using this as a back door to get run as soon as they are
15932            // installed.  Maybe in the future we want to have a special install
15933            // broadcast or such for apps, but we'd like to deliberately make
15934            // this decision.
15935            String skipPackages[] = null;
15936            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15937                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15938                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15939                Uri data = intent.getData();
15940                if (data != null) {
15941                    String pkgName = data.getSchemeSpecificPart();
15942                    if (pkgName != null) {
15943                        skipPackages = new String[] { pkgName };
15944                    }
15945                }
15946            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15947                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15948            }
15949            if (skipPackages != null && (skipPackages.length > 0)) {
15950                for (String skipPackage : skipPackages) {
15951                    if (skipPackage != null) {
15952                        int NT = receivers.size();
15953                        for (int it=0; it<NT; it++) {
15954                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15955                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15956                                receivers.remove(it);
15957                                it--;
15958                                NT--;
15959                            }
15960                        }
15961                    }
15962                }
15963            }
15964
15965            int NT = receivers != null ? receivers.size() : 0;
15966            int it = 0;
15967            ResolveInfo curt = null;
15968            BroadcastFilter curr = null;
15969            while (it < NT && ir < NR) {
15970                if (curt == null) {
15971                    curt = (ResolveInfo)receivers.get(it);
15972                }
15973                if (curr == null) {
15974                    curr = registeredReceivers.get(ir);
15975                }
15976                if (curr.getPriority() >= curt.priority) {
15977                    // Insert this broadcast record into the final list.
15978                    receivers.add(it, curr);
15979                    ir++;
15980                    curr = null;
15981                    it++;
15982                    NT++;
15983                } else {
15984                    // Skip to the next ResolveInfo in the final list.
15985                    it++;
15986                    curt = null;
15987                }
15988            }
15989        }
15990        while (ir < NR) {
15991            if (receivers == null) {
15992                receivers = new ArrayList();
15993            }
15994            receivers.add(registeredReceivers.get(ir));
15995            ir++;
15996        }
15997
15998        if ((receivers != null && receivers.size() > 0)
15999                || resultTo != null) {
16000            BroadcastQueue queue = broadcastQueueForIntent(intent);
16001            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16002                    callerPackage, callingPid, callingUid, resolvedType,
16003                    requiredPermission, appOp, receivers, resultTo, resultCode,
16004                    resultData, map, ordered, sticky, false, userId);
16005            if (DEBUG_BROADCAST) Slog.v(
16006                    TAG, "Enqueueing ordered broadcast " + r
16007                    + ": prev had " + queue.mOrderedBroadcasts.size());
16008            if (DEBUG_BROADCAST) {
16009                int seq = r.intent.getIntExtra("seq", -1);
16010                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16011            }
16012            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16013            if (!replaced) {
16014                queue.enqueueOrderedBroadcastLocked(r);
16015                queue.scheduleBroadcastsLocked();
16016            }
16017        }
16018
16019        return ActivityManager.BROADCAST_SUCCESS;
16020    }
16021
16022    final Intent verifyBroadcastLocked(Intent intent) {
16023        // Refuse possible leaked file descriptors
16024        if (intent != null && intent.hasFileDescriptors() == true) {
16025            throw new IllegalArgumentException("File descriptors passed in Intent");
16026        }
16027
16028        int flags = intent.getFlags();
16029
16030        if (!mProcessesReady) {
16031            // if the caller really truly claims to know what they're doing, go
16032            // ahead and allow the broadcast without launching any receivers
16033            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16034                intent = new Intent(intent);
16035                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16036            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16037                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16038                        + " before boot completion");
16039                throw new IllegalStateException("Cannot broadcast before boot completed");
16040            }
16041        }
16042
16043        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16044            throw new IllegalArgumentException(
16045                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16046        }
16047
16048        return intent;
16049    }
16050
16051    public final int broadcastIntent(IApplicationThread caller,
16052            Intent intent, String resolvedType, IIntentReceiver resultTo,
16053            int resultCode, String resultData, Bundle map,
16054            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16055        enforceNotIsolatedCaller("broadcastIntent");
16056        synchronized(this) {
16057            intent = verifyBroadcastLocked(intent);
16058
16059            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16060            final int callingPid = Binder.getCallingPid();
16061            final int callingUid = Binder.getCallingUid();
16062            final long origId = Binder.clearCallingIdentity();
16063            int res = broadcastIntentLocked(callerApp,
16064                    callerApp != null ? callerApp.info.packageName : null,
16065                    intent, resolvedType, resultTo,
16066                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16067                    callingPid, callingUid, userId);
16068            Binder.restoreCallingIdentity(origId);
16069            return res;
16070        }
16071    }
16072
16073    int broadcastIntentInPackage(String packageName, int uid,
16074            Intent intent, String resolvedType, IIntentReceiver resultTo,
16075            int resultCode, String resultData, Bundle map,
16076            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16077        synchronized(this) {
16078            intent = verifyBroadcastLocked(intent);
16079
16080            final long origId = Binder.clearCallingIdentity();
16081            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16082                    resultTo, resultCode, resultData, map, requiredPermission,
16083                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16084            Binder.restoreCallingIdentity(origId);
16085            return res;
16086        }
16087    }
16088
16089    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16090        // Refuse possible leaked file descriptors
16091        if (intent != null && intent.hasFileDescriptors() == true) {
16092            throw new IllegalArgumentException("File descriptors passed in Intent");
16093        }
16094
16095        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16096                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16097
16098        synchronized(this) {
16099            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16100                    != PackageManager.PERMISSION_GRANTED) {
16101                String msg = "Permission Denial: unbroadcastIntent() from pid="
16102                        + Binder.getCallingPid()
16103                        + ", uid=" + Binder.getCallingUid()
16104                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16105                Slog.w(TAG, msg);
16106                throw new SecurityException(msg);
16107            }
16108            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16109            if (stickies != null) {
16110                ArrayList<Intent> list = stickies.get(intent.getAction());
16111                if (list != null) {
16112                    int N = list.size();
16113                    int i;
16114                    for (i=0; i<N; i++) {
16115                        if (intent.filterEquals(list.get(i))) {
16116                            list.remove(i);
16117                            break;
16118                        }
16119                    }
16120                    if (list.size() <= 0) {
16121                        stickies.remove(intent.getAction());
16122                    }
16123                }
16124                if (stickies.size() <= 0) {
16125                    mStickyBroadcasts.remove(userId);
16126                }
16127            }
16128        }
16129    }
16130
16131    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16132            String resultData, Bundle resultExtras, boolean resultAbort) {
16133        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16134        if (r == null) {
16135            Slog.w(TAG, "finishReceiver called but not found on queue");
16136            return false;
16137        }
16138
16139        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16140    }
16141
16142    void backgroundServicesFinishedLocked(int userId) {
16143        for (BroadcastQueue queue : mBroadcastQueues) {
16144            queue.backgroundServicesFinishedLocked(userId);
16145        }
16146    }
16147
16148    public void finishReceiver(IBinder who, int resultCode, String resultData,
16149            Bundle resultExtras, boolean resultAbort) {
16150        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16151
16152        // Refuse possible leaked file descriptors
16153        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16154            throw new IllegalArgumentException("File descriptors passed in Bundle");
16155        }
16156
16157        final long origId = Binder.clearCallingIdentity();
16158        try {
16159            boolean doNext = false;
16160            BroadcastRecord r;
16161
16162            synchronized(this) {
16163                r = broadcastRecordForReceiverLocked(who);
16164                if (r != null) {
16165                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16166                        resultData, resultExtras, resultAbort, true);
16167                }
16168            }
16169
16170            if (doNext) {
16171                r.queue.processNextBroadcast(false);
16172            }
16173            trimApplications();
16174        } finally {
16175            Binder.restoreCallingIdentity(origId);
16176        }
16177    }
16178
16179    // =========================================================
16180    // INSTRUMENTATION
16181    // =========================================================
16182
16183    public boolean startInstrumentation(ComponentName className,
16184            String profileFile, int flags, Bundle arguments,
16185            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16186            int userId, String abiOverride) {
16187        enforceNotIsolatedCaller("startInstrumentation");
16188        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16189                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16190        // Refuse possible leaked file descriptors
16191        if (arguments != null && arguments.hasFileDescriptors()) {
16192            throw new IllegalArgumentException("File descriptors passed in Bundle");
16193        }
16194
16195        synchronized(this) {
16196            InstrumentationInfo ii = null;
16197            ApplicationInfo ai = null;
16198            try {
16199                ii = mContext.getPackageManager().getInstrumentationInfo(
16200                    className, STOCK_PM_FLAGS);
16201                ai = AppGlobals.getPackageManager().getApplicationInfo(
16202                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16203            } catch (PackageManager.NameNotFoundException e) {
16204            } catch (RemoteException e) {
16205            }
16206            if (ii == null) {
16207                reportStartInstrumentationFailure(watcher, className,
16208                        "Unable to find instrumentation info for: " + className);
16209                return false;
16210            }
16211            if (ai == null) {
16212                reportStartInstrumentationFailure(watcher, className,
16213                        "Unable to find instrumentation target package: " + ii.targetPackage);
16214                return false;
16215            }
16216
16217            int match = mContext.getPackageManager().checkSignatures(
16218                    ii.targetPackage, ii.packageName);
16219            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16220                String msg = "Permission Denial: starting instrumentation "
16221                        + className + " from pid="
16222                        + Binder.getCallingPid()
16223                        + ", uid=" + Binder.getCallingPid()
16224                        + " not allowed because package " + ii.packageName
16225                        + " does not have a signature matching the target "
16226                        + ii.targetPackage;
16227                reportStartInstrumentationFailure(watcher, className, msg);
16228                throw new SecurityException(msg);
16229            }
16230
16231            final long origId = Binder.clearCallingIdentity();
16232            // Instrumentation can kill and relaunch even persistent processes
16233            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16234                    "start instr");
16235            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16236            app.instrumentationClass = className;
16237            app.instrumentationInfo = ai;
16238            app.instrumentationProfileFile = profileFile;
16239            app.instrumentationArguments = arguments;
16240            app.instrumentationWatcher = watcher;
16241            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16242            app.instrumentationResultClass = className;
16243            Binder.restoreCallingIdentity(origId);
16244        }
16245
16246        return true;
16247    }
16248
16249    /**
16250     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16251     * error to the logs, but if somebody is watching, send the report there too.  This enables
16252     * the "am" command to report errors with more information.
16253     *
16254     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16255     * @param cn The component name of the instrumentation.
16256     * @param report The error report.
16257     */
16258    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16259            ComponentName cn, String report) {
16260        Slog.w(TAG, report);
16261        try {
16262            if (watcher != null) {
16263                Bundle results = new Bundle();
16264                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16265                results.putString("Error", report);
16266                watcher.instrumentationStatus(cn, -1, results);
16267            }
16268        } catch (RemoteException e) {
16269            Slog.w(TAG, e);
16270        }
16271    }
16272
16273    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16274        if (app.instrumentationWatcher != null) {
16275            try {
16276                // NOTE:  IInstrumentationWatcher *must* be oneway here
16277                app.instrumentationWatcher.instrumentationFinished(
16278                    app.instrumentationClass,
16279                    resultCode,
16280                    results);
16281            } catch (RemoteException e) {
16282            }
16283        }
16284        if (app.instrumentationUiAutomationConnection != null) {
16285            try {
16286                app.instrumentationUiAutomationConnection.shutdown();
16287            } catch (RemoteException re) {
16288                /* ignore */
16289            }
16290            // Only a UiAutomation can set this flag and now that
16291            // it is finished we make sure it is reset to its default.
16292            mUserIsMonkey = false;
16293        }
16294        app.instrumentationWatcher = null;
16295        app.instrumentationUiAutomationConnection = null;
16296        app.instrumentationClass = null;
16297        app.instrumentationInfo = null;
16298        app.instrumentationProfileFile = null;
16299        app.instrumentationArguments = null;
16300
16301        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16302                "finished inst");
16303    }
16304
16305    public void finishInstrumentation(IApplicationThread target,
16306            int resultCode, Bundle results) {
16307        int userId = UserHandle.getCallingUserId();
16308        // Refuse possible leaked file descriptors
16309        if (results != null && results.hasFileDescriptors()) {
16310            throw new IllegalArgumentException("File descriptors passed in Intent");
16311        }
16312
16313        synchronized(this) {
16314            ProcessRecord app = getRecordForAppLocked(target);
16315            if (app == null) {
16316                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16317                return;
16318            }
16319            final long origId = Binder.clearCallingIdentity();
16320            finishInstrumentationLocked(app, resultCode, results);
16321            Binder.restoreCallingIdentity(origId);
16322        }
16323    }
16324
16325    // =========================================================
16326    // CONFIGURATION
16327    // =========================================================
16328
16329    public ConfigurationInfo getDeviceConfigurationInfo() {
16330        ConfigurationInfo config = new ConfigurationInfo();
16331        synchronized (this) {
16332            config.reqTouchScreen = mConfiguration.touchscreen;
16333            config.reqKeyboardType = mConfiguration.keyboard;
16334            config.reqNavigation = mConfiguration.navigation;
16335            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16336                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16337                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16338            }
16339            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16340                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16341                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16342            }
16343            config.reqGlEsVersion = GL_ES_VERSION;
16344        }
16345        return config;
16346    }
16347
16348    ActivityStack getFocusedStack() {
16349        return mStackSupervisor.getFocusedStack();
16350    }
16351
16352    public Configuration getConfiguration() {
16353        Configuration ci;
16354        synchronized(this) {
16355            ci = new Configuration(mConfiguration);
16356        }
16357        return ci;
16358    }
16359
16360    public void updatePersistentConfiguration(Configuration values) {
16361        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16362                "updateConfiguration()");
16363        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16364                "updateConfiguration()");
16365        if (values == null) {
16366            throw new NullPointerException("Configuration must not be null");
16367        }
16368
16369        synchronized(this) {
16370            final long origId = Binder.clearCallingIdentity();
16371            updateConfigurationLocked(values, null, true, false);
16372            Binder.restoreCallingIdentity(origId);
16373        }
16374    }
16375
16376    public void updateConfiguration(Configuration values) {
16377        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16378                "updateConfiguration()");
16379
16380        synchronized(this) {
16381            if (values == null && mWindowManager != null) {
16382                // sentinel: fetch the current configuration from the window manager
16383                values = mWindowManager.computeNewConfiguration();
16384            }
16385
16386            if (mWindowManager != null) {
16387                mProcessList.applyDisplaySize(mWindowManager);
16388            }
16389
16390            final long origId = Binder.clearCallingIdentity();
16391            if (values != null) {
16392                Settings.System.clearConfiguration(values);
16393            }
16394            updateConfigurationLocked(values, null, false, false);
16395            Binder.restoreCallingIdentity(origId);
16396        }
16397    }
16398
16399    /**
16400     * Do either or both things: (1) change the current configuration, and (2)
16401     * make sure the given activity is running with the (now) current
16402     * configuration.  Returns true if the activity has been left running, or
16403     * false if <var>starting</var> is being destroyed to match the new
16404     * configuration.
16405     * @param persistent TODO
16406     */
16407    boolean updateConfigurationLocked(Configuration values,
16408            ActivityRecord starting, boolean persistent, boolean initLocale) {
16409        int changes = 0;
16410
16411        if (values != null) {
16412            Configuration newConfig = new Configuration(mConfiguration);
16413            changes = newConfig.updateFrom(values);
16414            if (changes != 0) {
16415                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16416                    Slog.i(TAG, "Updating configuration to: " + values);
16417                }
16418
16419                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16420
16421                if (values.locale != null && !initLocale) {
16422                    saveLocaleLocked(values.locale,
16423                                     !values.locale.equals(mConfiguration.locale),
16424                                     values.userSetLocale);
16425                }
16426
16427                mConfigurationSeq++;
16428                if (mConfigurationSeq <= 0) {
16429                    mConfigurationSeq = 1;
16430                }
16431                newConfig.seq = mConfigurationSeq;
16432                mConfiguration = newConfig;
16433                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16434                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16435                //mUsageStatsService.noteStartConfig(newConfig);
16436
16437                final Configuration configCopy = new Configuration(mConfiguration);
16438
16439                // TODO: If our config changes, should we auto dismiss any currently
16440                // showing dialogs?
16441                mShowDialogs = shouldShowDialogs(newConfig);
16442
16443                AttributeCache ac = AttributeCache.instance();
16444                if (ac != null) {
16445                    ac.updateConfiguration(configCopy);
16446                }
16447
16448                // Make sure all resources in our process are updated
16449                // right now, so that anyone who is going to retrieve
16450                // resource values after we return will be sure to get
16451                // the new ones.  This is especially important during
16452                // boot, where the first config change needs to guarantee
16453                // all resources have that config before following boot
16454                // code is executed.
16455                mSystemThread.applyConfigurationToResources(configCopy);
16456
16457                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16458                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16459                    msg.obj = new Configuration(configCopy);
16460                    mHandler.sendMessage(msg);
16461                }
16462
16463                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16464                    ProcessRecord app = mLruProcesses.get(i);
16465                    try {
16466                        if (app.thread != null) {
16467                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16468                                    + app.processName + " new config " + mConfiguration);
16469                            app.thread.scheduleConfigurationChanged(configCopy);
16470                        }
16471                    } catch (Exception e) {
16472                    }
16473                }
16474                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16475                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16476                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16477                        | Intent.FLAG_RECEIVER_FOREGROUND);
16478                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16479                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16480                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16481                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16482                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16483                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16484                    broadcastIntentLocked(null, null, intent,
16485                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16486                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16487                }
16488            }
16489        }
16490
16491        boolean kept = true;
16492        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16493        // mainStack is null during startup.
16494        if (mainStack != null) {
16495            if (changes != 0 && starting == null) {
16496                // If the configuration changed, and the caller is not already
16497                // in the process of starting an activity, then find the top
16498                // activity to check if its configuration needs to change.
16499                starting = mainStack.topRunningActivityLocked(null);
16500            }
16501
16502            if (starting != null) {
16503                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16504                // And we need to make sure at this point that all other activities
16505                // are made visible with the correct configuration.
16506                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16507            }
16508        }
16509
16510        if (values != null && mWindowManager != null) {
16511            mWindowManager.setNewConfiguration(mConfiguration);
16512        }
16513
16514        return kept;
16515    }
16516
16517    /**
16518     * Decide based on the configuration whether we should shouw the ANR,
16519     * crash, etc dialogs.  The idea is that if there is no affordnace to
16520     * press the on-screen buttons, we shouldn't show the dialog.
16521     *
16522     * A thought: SystemUI might also want to get told about this, the Power
16523     * dialog / global actions also might want different behaviors.
16524     */
16525    private static final boolean shouldShowDialogs(Configuration config) {
16526        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16527                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16528    }
16529
16530    /**
16531     * Save the locale.  You must be inside a synchronized (this) block.
16532     */
16533    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16534        if(isDiff) {
16535            SystemProperties.set("user.language", l.getLanguage());
16536            SystemProperties.set("user.region", l.getCountry());
16537        }
16538
16539        if(isPersist) {
16540            SystemProperties.set("persist.sys.language", l.getLanguage());
16541            SystemProperties.set("persist.sys.country", l.getCountry());
16542            SystemProperties.set("persist.sys.localevar", l.getVariant());
16543
16544            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16545        }
16546    }
16547
16548    @Override
16549    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16550        synchronized (this) {
16551            ActivityRecord srec = ActivityRecord.forToken(token);
16552            if (srec.task != null && srec.task.stack != null) {
16553                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16554            }
16555        }
16556        return false;
16557    }
16558
16559    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16560            Intent resultData) {
16561
16562        synchronized (this) {
16563            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16564            if (stack != null) {
16565                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16566            }
16567            return false;
16568        }
16569    }
16570
16571    public int getLaunchedFromUid(IBinder activityToken) {
16572        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16573        if (srec == null) {
16574            return -1;
16575        }
16576        return srec.launchedFromUid;
16577    }
16578
16579    public String getLaunchedFromPackage(IBinder activityToken) {
16580        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16581        if (srec == null) {
16582            return null;
16583        }
16584        return srec.launchedFromPackage;
16585    }
16586
16587    // =========================================================
16588    // LIFETIME MANAGEMENT
16589    // =========================================================
16590
16591    // Returns which broadcast queue the app is the current [or imminent] receiver
16592    // on, or 'null' if the app is not an active broadcast recipient.
16593    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16594        BroadcastRecord r = app.curReceiver;
16595        if (r != null) {
16596            return r.queue;
16597        }
16598
16599        // It's not the current receiver, but it might be starting up to become one
16600        synchronized (this) {
16601            for (BroadcastQueue queue : mBroadcastQueues) {
16602                r = queue.mPendingBroadcast;
16603                if (r != null && r.curApp == app) {
16604                    // found it; report which queue it's in
16605                    return queue;
16606                }
16607            }
16608        }
16609
16610        return null;
16611    }
16612
16613    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16614            boolean doingAll, long now) {
16615        if (mAdjSeq == app.adjSeq) {
16616            // This adjustment has already been computed.
16617            return app.curRawAdj;
16618        }
16619
16620        if (app.thread == null) {
16621            app.adjSeq = mAdjSeq;
16622            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16623            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16624            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16625        }
16626
16627        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16628        app.adjSource = null;
16629        app.adjTarget = null;
16630        app.empty = false;
16631        app.cached = false;
16632
16633        final int activitiesSize = app.activities.size();
16634
16635        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16636            // The max adjustment doesn't allow this app to be anything
16637            // below foreground, so it is not worth doing work for it.
16638            app.adjType = "fixed";
16639            app.adjSeq = mAdjSeq;
16640            app.curRawAdj = app.maxAdj;
16641            app.foregroundActivities = false;
16642            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16643            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16644            // System processes can do UI, and when they do we want to have
16645            // them trim their memory after the user leaves the UI.  To
16646            // facilitate this, here we need to determine whether or not it
16647            // is currently showing UI.
16648            app.systemNoUi = true;
16649            if (app == TOP_APP) {
16650                app.systemNoUi = false;
16651            } else if (activitiesSize > 0) {
16652                for (int j = 0; j < activitiesSize; j++) {
16653                    final ActivityRecord r = app.activities.get(j);
16654                    if (r.visible) {
16655                        app.systemNoUi = false;
16656                    }
16657                }
16658            }
16659            if (!app.systemNoUi) {
16660                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16661            }
16662            return (app.curAdj=app.maxAdj);
16663        }
16664
16665        app.systemNoUi = false;
16666
16667        // Determine the importance of the process, starting with most
16668        // important to least, and assign an appropriate OOM adjustment.
16669        int adj;
16670        int schedGroup;
16671        int procState;
16672        boolean foregroundActivities = false;
16673        BroadcastQueue queue;
16674        if (app == TOP_APP) {
16675            // The last app on the list is the foreground app.
16676            adj = ProcessList.FOREGROUND_APP_ADJ;
16677            schedGroup = Process.THREAD_GROUP_DEFAULT;
16678            app.adjType = "top-activity";
16679            foregroundActivities = true;
16680            procState = ActivityManager.PROCESS_STATE_TOP;
16681        } else if (app.instrumentationClass != null) {
16682            // Don't want to kill running instrumentation.
16683            adj = ProcessList.FOREGROUND_APP_ADJ;
16684            schedGroup = Process.THREAD_GROUP_DEFAULT;
16685            app.adjType = "instrumentation";
16686            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16687        } else if ((queue = isReceivingBroadcast(app)) != null) {
16688            // An app that is currently receiving a broadcast also
16689            // counts as being in the foreground for OOM killer purposes.
16690            // It's placed in a sched group based on the nature of the
16691            // broadcast as reflected by which queue it's active in.
16692            adj = ProcessList.FOREGROUND_APP_ADJ;
16693            schedGroup = (queue == mFgBroadcastQueue)
16694                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16695            app.adjType = "broadcast";
16696            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16697        } else if (app.executingServices.size() > 0) {
16698            // An app that is currently executing a service callback also
16699            // counts as being in the foreground.
16700            adj = ProcessList.FOREGROUND_APP_ADJ;
16701            schedGroup = app.execServicesFg ?
16702                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16703            app.adjType = "exec-service";
16704            procState = ActivityManager.PROCESS_STATE_SERVICE;
16705            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16706        } else {
16707            // As far as we know the process is empty.  We may change our mind later.
16708            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16709            // At this point we don't actually know the adjustment.  Use the cached adj
16710            // value that the caller wants us to.
16711            adj = cachedAdj;
16712            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16713            app.cached = true;
16714            app.empty = true;
16715            app.adjType = "cch-empty";
16716        }
16717
16718        // Examine all activities if not already foreground.
16719        if (!foregroundActivities && activitiesSize > 0) {
16720            for (int j = 0; j < activitiesSize; j++) {
16721                final ActivityRecord r = app.activities.get(j);
16722                if (r.app != app) {
16723                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16724                            + app + "?!?");
16725                    continue;
16726                }
16727                if (r.visible) {
16728                    // App has a visible activity; only upgrade adjustment.
16729                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16730                        adj = ProcessList.VISIBLE_APP_ADJ;
16731                        app.adjType = "visible";
16732                    }
16733                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16734                        procState = ActivityManager.PROCESS_STATE_TOP;
16735                    }
16736                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16737                    app.cached = false;
16738                    app.empty = false;
16739                    foregroundActivities = true;
16740                    break;
16741                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16742                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16743                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16744                        app.adjType = "pausing";
16745                    }
16746                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16747                        procState = ActivityManager.PROCESS_STATE_TOP;
16748                    }
16749                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16750                    app.cached = false;
16751                    app.empty = false;
16752                    foregroundActivities = true;
16753                } else if (r.state == ActivityState.STOPPING) {
16754                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16755                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16756                        app.adjType = "stopping";
16757                    }
16758                    // For the process state, we will at this point consider the
16759                    // process to be cached.  It will be cached either as an activity
16760                    // or empty depending on whether the activity is finishing.  We do
16761                    // this so that we can treat the process as cached for purposes of
16762                    // memory trimming (determing current memory level, trim command to
16763                    // send to process) since there can be an arbitrary number of stopping
16764                    // processes and they should soon all go into the cached state.
16765                    if (!r.finishing) {
16766                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16767                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16768                        }
16769                    }
16770                    app.cached = false;
16771                    app.empty = false;
16772                    foregroundActivities = true;
16773                } else {
16774                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16775                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16776                        app.adjType = "cch-act";
16777                    }
16778                }
16779            }
16780        }
16781
16782        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16783            if (app.foregroundServices) {
16784                // The user is aware of this app, so make it visible.
16785                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16786                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16787                app.cached = false;
16788                app.adjType = "fg-service";
16789                schedGroup = Process.THREAD_GROUP_DEFAULT;
16790            } else if (app.forcingToForeground != null) {
16791                // The user is aware of this app, so make it visible.
16792                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16793                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16794                app.cached = false;
16795                app.adjType = "force-fg";
16796                app.adjSource = app.forcingToForeground;
16797                schedGroup = Process.THREAD_GROUP_DEFAULT;
16798            }
16799        }
16800
16801        if (app == mHeavyWeightProcess) {
16802            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16803                // We don't want to kill the current heavy-weight process.
16804                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16805                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16806                app.cached = false;
16807                app.adjType = "heavy";
16808            }
16809            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16810                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16811            }
16812        }
16813
16814        if (app == mHomeProcess) {
16815            if (adj > ProcessList.HOME_APP_ADJ) {
16816                // This process is hosting what we currently consider to be the
16817                // home app, so we don't want to let it go into the background.
16818                adj = ProcessList.HOME_APP_ADJ;
16819                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16820                app.cached = false;
16821                app.adjType = "home";
16822            }
16823            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16824                procState = ActivityManager.PROCESS_STATE_HOME;
16825            }
16826        }
16827
16828        if (app == mPreviousProcess && app.activities.size() > 0) {
16829            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16830                // This was the previous process that showed UI to the user.
16831                // We want to try to keep it around more aggressively, to give
16832                // a good experience around switching between two apps.
16833                adj = ProcessList.PREVIOUS_APP_ADJ;
16834                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16835                app.cached = false;
16836                app.adjType = "previous";
16837            }
16838            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16839                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16840            }
16841        }
16842
16843        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16844                + " reason=" + app.adjType);
16845
16846        // By default, we use the computed adjustment.  It may be changed if
16847        // there are applications dependent on our services or providers, but
16848        // this gives us a baseline and makes sure we don't get into an
16849        // infinite recursion.
16850        app.adjSeq = mAdjSeq;
16851        app.curRawAdj = adj;
16852        app.hasStartedServices = false;
16853
16854        if (mBackupTarget != null && app == mBackupTarget.app) {
16855            // If possible we want to avoid killing apps while they're being backed up
16856            if (adj > ProcessList.BACKUP_APP_ADJ) {
16857                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16858                adj = ProcessList.BACKUP_APP_ADJ;
16859                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16860                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16861                }
16862                app.adjType = "backup";
16863                app.cached = false;
16864            }
16865            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16866                procState = ActivityManager.PROCESS_STATE_BACKUP;
16867            }
16868        }
16869
16870        boolean mayBeTop = false;
16871
16872        for (int is = app.services.size()-1;
16873                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16874                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16875                        || procState > ActivityManager.PROCESS_STATE_TOP);
16876                is--) {
16877            ServiceRecord s = app.services.valueAt(is);
16878            if (s.startRequested) {
16879                app.hasStartedServices = true;
16880                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16881                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16882                }
16883                if (app.hasShownUi && app != mHomeProcess) {
16884                    // If this process has shown some UI, let it immediately
16885                    // go to the LRU list because it may be pretty heavy with
16886                    // UI stuff.  We'll tag it with a label just to help
16887                    // debug and understand what is going on.
16888                    if (adj > ProcessList.SERVICE_ADJ) {
16889                        app.adjType = "cch-started-ui-services";
16890                    }
16891                } else {
16892                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16893                        // This service has seen some activity within
16894                        // recent memory, so we will keep its process ahead
16895                        // of the background processes.
16896                        if (adj > ProcessList.SERVICE_ADJ) {
16897                            adj = ProcessList.SERVICE_ADJ;
16898                            app.adjType = "started-services";
16899                            app.cached = false;
16900                        }
16901                    }
16902                    // If we have let the service slide into the background
16903                    // state, still have some text describing what it is doing
16904                    // even though the service no longer has an impact.
16905                    if (adj > ProcessList.SERVICE_ADJ) {
16906                        app.adjType = "cch-started-services";
16907                    }
16908                }
16909            }
16910            for (int conni = s.connections.size()-1;
16911                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16912                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16913                            || procState > ActivityManager.PROCESS_STATE_TOP);
16914                    conni--) {
16915                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16916                for (int i = 0;
16917                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16918                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16919                                || procState > ActivityManager.PROCESS_STATE_TOP);
16920                        i++) {
16921                    // XXX should compute this based on the max of
16922                    // all connected clients.
16923                    ConnectionRecord cr = clist.get(i);
16924                    if (cr.binding.client == app) {
16925                        // Binding to ourself is not interesting.
16926                        continue;
16927                    }
16928                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16929                        ProcessRecord client = cr.binding.client;
16930                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16931                                TOP_APP, doingAll, now);
16932                        int clientProcState = client.curProcState;
16933                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16934                            // If the other app is cached for any reason, for purposes here
16935                            // we are going to consider it empty.  The specific cached state
16936                            // doesn't propagate except under certain conditions.
16937                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16938                        }
16939                        String adjType = null;
16940                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16941                            // Not doing bind OOM management, so treat
16942                            // this guy more like a started service.
16943                            if (app.hasShownUi && app != mHomeProcess) {
16944                                // If this process has shown some UI, let it immediately
16945                                // go to the LRU list because it may be pretty heavy with
16946                                // UI stuff.  We'll tag it with a label just to help
16947                                // debug and understand what is going on.
16948                                if (adj > clientAdj) {
16949                                    adjType = "cch-bound-ui-services";
16950                                }
16951                                app.cached = false;
16952                                clientAdj = adj;
16953                                clientProcState = procState;
16954                            } else {
16955                                if (now >= (s.lastActivity
16956                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16957                                    // This service has not seen activity within
16958                                    // recent memory, so allow it to drop to the
16959                                    // LRU list if there is no other reason to keep
16960                                    // it around.  We'll also tag it with a label just
16961                                    // to help debug and undertand what is going on.
16962                                    if (adj > clientAdj) {
16963                                        adjType = "cch-bound-services";
16964                                    }
16965                                    clientAdj = adj;
16966                                }
16967                            }
16968                        }
16969                        if (adj > clientAdj) {
16970                            // If this process has recently shown UI, and
16971                            // the process that is binding to it is less
16972                            // important than being visible, then we don't
16973                            // care about the binding as much as we care
16974                            // about letting this process get into the LRU
16975                            // list to be killed and restarted if needed for
16976                            // memory.
16977                            if (app.hasShownUi && app != mHomeProcess
16978                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16979                                adjType = "cch-bound-ui-services";
16980                            } else {
16981                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16982                                        |Context.BIND_IMPORTANT)) != 0) {
16983                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16984                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16985                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16986                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16987                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16988                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16989                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16990                                    adj = clientAdj;
16991                                } else {
16992                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16993                                        adj = ProcessList.VISIBLE_APP_ADJ;
16994                                    }
16995                                }
16996                                if (!client.cached) {
16997                                    app.cached = false;
16998                                }
16999                                adjType = "service";
17000                            }
17001                        }
17002                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17003                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17004                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17005                            }
17006                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17007                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17008                                    // Special handling of clients who are in the top state.
17009                                    // We *may* want to consider this process to be in the
17010                                    // top state as well, but only if there is not another
17011                                    // reason for it to be running.  Being on the top is a
17012                                    // special state, meaning you are specifically running
17013                                    // for the current top app.  If the process is already
17014                                    // running in the background for some other reason, it
17015                                    // is more important to continue considering it to be
17016                                    // in the background state.
17017                                    mayBeTop = true;
17018                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17019                                } else {
17020                                    // Special handling for above-top states (persistent
17021                                    // processes).  These should not bring the current process
17022                                    // into the top state, since they are not on top.  Instead
17023                                    // give them the best state after that.
17024                                    clientProcState =
17025                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17026                                }
17027                            }
17028                        } else {
17029                            if (clientProcState <
17030                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17031                                clientProcState =
17032                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17033                            }
17034                        }
17035                        if (procState > clientProcState) {
17036                            procState = clientProcState;
17037                        }
17038                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17039                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17040                            app.pendingUiClean = true;
17041                        }
17042                        if (adjType != null) {
17043                            app.adjType = adjType;
17044                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17045                                    .REASON_SERVICE_IN_USE;
17046                            app.adjSource = cr.binding.client;
17047                            app.adjSourceProcState = clientProcState;
17048                            app.adjTarget = s.name;
17049                        }
17050                    }
17051                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17052                        app.treatLikeActivity = true;
17053                    }
17054                    final ActivityRecord a = cr.activity;
17055                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17056                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17057                                (a.visible || a.state == ActivityState.RESUMED
17058                                 || a.state == ActivityState.PAUSING)) {
17059                            adj = ProcessList.FOREGROUND_APP_ADJ;
17060                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17061                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17062                            }
17063                            app.cached = false;
17064                            app.adjType = "service";
17065                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17066                                    .REASON_SERVICE_IN_USE;
17067                            app.adjSource = a;
17068                            app.adjSourceProcState = procState;
17069                            app.adjTarget = s.name;
17070                        }
17071                    }
17072                }
17073            }
17074        }
17075
17076        for (int provi = app.pubProviders.size()-1;
17077                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17078                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17079                        || procState > ActivityManager.PROCESS_STATE_TOP);
17080                provi--) {
17081            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17082            for (int i = cpr.connections.size()-1;
17083                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17084                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17085                            || procState > ActivityManager.PROCESS_STATE_TOP);
17086                    i--) {
17087                ContentProviderConnection conn = cpr.connections.get(i);
17088                ProcessRecord client = conn.client;
17089                if (client == app) {
17090                    // Being our own client is not interesting.
17091                    continue;
17092                }
17093                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17094                int clientProcState = client.curProcState;
17095                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17096                    // If the other app is cached for any reason, for purposes here
17097                    // we are going to consider it empty.
17098                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17099                }
17100                if (adj > clientAdj) {
17101                    if (app.hasShownUi && app != mHomeProcess
17102                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17103                        app.adjType = "cch-ui-provider";
17104                    } else {
17105                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17106                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17107                        app.adjType = "provider";
17108                    }
17109                    app.cached &= client.cached;
17110                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17111                            .REASON_PROVIDER_IN_USE;
17112                    app.adjSource = client;
17113                    app.adjSourceProcState = clientProcState;
17114                    app.adjTarget = cpr.name;
17115                }
17116                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17117                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17118                        // Special handling of clients who are in the top state.
17119                        // We *may* want to consider this process to be in the
17120                        // top state as well, but only if there is not another
17121                        // reason for it to be running.  Being on the top is a
17122                        // special state, meaning you are specifically running
17123                        // for the current top app.  If the process is already
17124                        // running in the background for some other reason, it
17125                        // is more important to continue considering it to be
17126                        // in the background state.
17127                        mayBeTop = true;
17128                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17129                    } else {
17130                        // Special handling for above-top states (persistent
17131                        // processes).  These should not bring the current process
17132                        // into the top state, since they are not on top.  Instead
17133                        // give them the best state after that.
17134                        clientProcState =
17135                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17136                    }
17137                }
17138                if (procState > clientProcState) {
17139                    procState = clientProcState;
17140                }
17141                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17142                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17143                }
17144            }
17145            // If the provider has external (non-framework) process
17146            // dependencies, ensure that its adjustment is at least
17147            // FOREGROUND_APP_ADJ.
17148            if (cpr.hasExternalProcessHandles()) {
17149                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17150                    adj = ProcessList.FOREGROUND_APP_ADJ;
17151                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17152                    app.cached = false;
17153                    app.adjType = "provider";
17154                    app.adjTarget = cpr.name;
17155                }
17156                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17157                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17158                }
17159            }
17160        }
17161
17162        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17163            // A client of one of our services or providers is in the top state.  We
17164            // *may* want to be in the top state, but not if we are already running in
17165            // the background for some other reason.  For the decision here, we are going
17166            // to pick out a few specific states that we want to remain in when a client
17167            // is top (states that tend to be longer-term) and otherwise allow it to go
17168            // to the top state.
17169            switch (procState) {
17170                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17171                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17172                case ActivityManager.PROCESS_STATE_SERVICE:
17173                    // These all are longer-term states, so pull them up to the top
17174                    // of the background states, but not all the way to the top state.
17175                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17176                    break;
17177                default:
17178                    // Otherwise, top is a better choice, so take it.
17179                    procState = ActivityManager.PROCESS_STATE_TOP;
17180                    break;
17181            }
17182        }
17183
17184        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17185            if (app.hasClientActivities) {
17186                // This is a cached process, but with client activities.  Mark it so.
17187                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17188                app.adjType = "cch-client-act";
17189            } else if (app.treatLikeActivity) {
17190                // This is a cached process, but somebody wants us to treat it like it has
17191                // an activity, okay!
17192                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17193                app.adjType = "cch-as-act";
17194            }
17195        }
17196
17197        if (adj == ProcessList.SERVICE_ADJ) {
17198            if (doingAll) {
17199                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17200                mNewNumServiceProcs++;
17201                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17202                if (!app.serviceb) {
17203                    // This service isn't far enough down on the LRU list to
17204                    // normally be a B service, but if we are low on RAM and it
17205                    // is large we want to force it down since we would prefer to
17206                    // keep launcher over it.
17207                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17208                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17209                        app.serviceHighRam = true;
17210                        app.serviceb = true;
17211                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17212                    } else {
17213                        mNewNumAServiceProcs++;
17214                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17215                    }
17216                } else {
17217                    app.serviceHighRam = false;
17218                }
17219            }
17220            if (app.serviceb) {
17221                adj = ProcessList.SERVICE_B_ADJ;
17222            }
17223        }
17224
17225        app.curRawAdj = adj;
17226
17227        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17228        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17229        if (adj > app.maxAdj) {
17230            adj = app.maxAdj;
17231            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17232                schedGroup = Process.THREAD_GROUP_DEFAULT;
17233            }
17234        }
17235
17236        // Do final modification to adj.  Everything we do between here and applying
17237        // the final setAdj must be done in this function, because we will also use
17238        // it when computing the final cached adj later.  Note that we don't need to
17239        // worry about this for max adj above, since max adj will always be used to
17240        // keep it out of the cached vaues.
17241        app.curAdj = app.modifyRawOomAdj(adj);
17242        app.curSchedGroup = schedGroup;
17243        app.curProcState = procState;
17244        app.foregroundActivities = foregroundActivities;
17245
17246        return app.curRawAdj;
17247    }
17248
17249    /**
17250     * Schedule PSS collection of a process.
17251     */
17252    void requestPssLocked(ProcessRecord proc, int procState) {
17253        if (mPendingPssProcesses.contains(proc)) {
17254            return;
17255        }
17256        if (mPendingPssProcesses.size() == 0) {
17257            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17258        }
17259        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17260        proc.pssProcState = procState;
17261        mPendingPssProcesses.add(proc);
17262    }
17263
17264    /**
17265     * Schedule PSS collection of all processes.
17266     */
17267    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17268        if (!always) {
17269            if (now < (mLastFullPssTime +
17270                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17271                return;
17272            }
17273        }
17274        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17275        mLastFullPssTime = now;
17276        mFullPssPending = true;
17277        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17278        mPendingPssProcesses.clear();
17279        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17280            ProcessRecord app = mLruProcesses.get(i);
17281            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17282                app.pssProcState = app.setProcState;
17283                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17284                        isSleeping(), now);
17285                mPendingPssProcesses.add(app);
17286            }
17287        }
17288        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17289    }
17290
17291    /**
17292     * Ask a given process to GC right now.
17293     */
17294    final void performAppGcLocked(ProcessRecord app) {
17295        try {
17296            app.lastRequestedGc = SystemClock.uptimeMillis();
17297            if (app.thread != null) {
17298                if (app.reportLowMemory) {
17299                    app.reportLowMemory = false;
17300                    app.thread.scheduleLowMemory();
17301                } else {
17302                    app.thread.processInBackground();
17303                }
17304            }
17305        } catch (Exception e) {
17306            // whatever.
17307        }
17308    }
17309
17310    /**
17311     * Returns true if things are idle enough to perform GCs.
17312     */
17313    private final boolean canGcNowLocked() {
17314        boolean processingBroadcasts = false;
17315        for (BroadcastQueue q : mBroadcastQueues) {
17316            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17317                processingBroadcasts = true;
17318            }
17319        }
17320        return !processingBroadcasts
17321                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17322    }
17323
17324    /**
17325     * Perform GCs on all processes that are waiting for it, but only
17326     * if things are idle.
17327     */
17328    final void performAppGcsLocked() {
17329        final int N = mProcessesToGc.size();
17330        if (N <= 0) {
17331            return;
17332        }
17333        if (canGcNowLocked()) {
17334            while (mProcessesToGc.size() > 0) {
17335                ProcessRecord proc = mProcessesToGc.remove(0);
17336                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17337                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17338                            <= SystemClock.uptimeMillis()) {
17339                        // To avoid spamming the system, we will GC processes one
17340                        // at a time, waiting a few seconds between each.
17341                        performAppGcLocked(proc);
17342                        scheduleAppGcsLocked();
17343                        return;
17344                    } else {
17345                        // It hasn't been long enough since we last GCed this
17346                        // process...  put it in the list to wait for its time.
17347                        addProcessToGcListLocked(proc);
17348                        break;
17349                    }
17350                }
17351            }
17352
17353            scheduleAppGcsLocked();
17354        }
17355    }
17356
17357    /**
17358     * If all looks good, perform GCs on all processes waiting for them.
17359     */
17360    final void performAppGcsIfAppropriateLocked() {
17361        if (canGcNowLocked()) {
17362            performAppGcsLocked();
17363            return;
17364        }
17365        // Still not idle, wait some more.
17366        scheduleAppGcsLocked();
17367    }
17368
17369    /**
17370     * Schedule the execution of all pending app GCs.
17371     */
17372    final void scheduleAppGcsLocked() {
17373        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17374
17375        if (mProcessesToGc.size() > 0) {
17376            // Schedule a GC for the time to the next process.
17377            ProcessRecord proc = mProcessesToGc.get(0);
17378            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17379
17380            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17381            long now = SystemClock.uptimeMillis();
17382            if (when < (now+GC_TIMEOUT)) {
17383                when = now + GC_TIMEOUT;
17384            }
17385            mHandler.sendMessageAtTime(msg, when);
17386        }
17387    }
17388
17389    /**
17390     * Add a process to the array of processes waiting to be GCed.  Keeps the
17391     * list in sorted order by the last GC time.  The process can't already be
17392     * on the list.
17393     */
17394    final void addProcessToGcListLocked(ProcessRecord proc) {
17395        boolean added = false;
17396        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17397            if (mProcessesToGc.get(i).lastRequestedGc <
17398                    proc.lastRequestedGc) {
17399                added = true;
17400                mProcessesToGc.add(i+1, proc);
17401                break;
17402            }
17403        }
17404        if (!added) {
17405            mProcessesToGc.add(0, proc);
17406        }
17407    }
17408
17409    /**
17410     * Set up to ask a process to GC itself.  This will either do it
17411     * immediately, or put it on the list of processes to gc the next
17412     * time things are idle.
17413     */
17414    final void scheduleAppGcLocked(ProcessRecord app) {
17415        long now = SystemClock.uptimeMillis();
17416        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17417            return;
17418        }
17419        if (!mProcessesToGc.contains(app)) {
17420            addProcessToGcListLocked(app);
17421            scheduleAppGcsLocked();
17422        }
17423    }
17424
17425    final void checkExcessivePowerUsageLocked(boolean doKills) {
17426        updateCpuStatsNow();
17427
17428        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17429        boolean doWakeKills = doKills;
17430        boolean doCpuKills = doKills;
17431        if (mLastPowerCheckRealtime == 0) {
17432            doWakeKills = false;
17433        }
17434        if (mLastPowerCheckUptime == 0) {
17435            doCpuKills = false;
17436        }
17437        if (stats.isScreenOn()) {
17438            doWakeKills = false;
17439        }
17440        final long curRealtime = SystemClock.elapsedRealtime();
17441        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17442        final long curUptime = SystemClock.uptimeMillis();
17443        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17444        mLastPowerCheckRealtime = curRealtime;
17445        mLastPowerCheckUptime = curUptime;
17446        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17447            doWakeKills = false;
17448        }
17449        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17450            doCpuKills = false;
17451        }
17452        int i = mLruProcesses.size();
17453        while (i > 0) {
17454            i--;
17455            ProcessRecord app = mLruProcesses.get(i);
17456            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17457                long wtime;
17458                synchronized (stats) {
17459                    wtime = stats.getProcessWakeTime(app.info.uid,
17460                            app.pid, curRealtime);
17461                }
17462                long wtimeUsed = wtime - app.lastWakeTime;
17463                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17464                if (DEBUG_POWER) {
17465                    StringBuilder sb = new StringBuilder(128);
17466                    sb.append("Wake for ");
17467                    app.toShortString(sb);
17468                    sb.append(": over ");
17469                    TimeUtils.formatDuration(realtimeSince, sb);
17470                    sb.append(" used ");
17471                    TimeUtils.formatDuration(wtimeUsed, sb);
17472                    sb.append(" (");
17473                    sb.append((wtimeUsed*100)/realtimeSince);
17474                    sb.append("%)");
17475                    Slog.i(TAG, sb.toString());
17476                    sb.setLength(0);
17477                    sb.append("CPU for ");
17478                    app.toShortString(sb);
17479                    sb.append(": over ");
17480                    TimeUtils.formatDuration(uptimeSince, sb);
17481                    sb.append(" used ");
17482                    TimeUtils.formatDuration(cputimeUsed, sb);
17483                    sb.append(" (");
17484                    sb.append((cputimeUsed*100)/uptimeSince);
17485                    sb.append("%)");
17486                    Slog.i(TAG, sb.toString());
17487                }
17488                // If a process has held a wake lock for more
17489                // than 50% of the time during this period,
17490                // that sounds bad.  Kill!
17491                if (doWakeKills && realtimeSince > 0
17492                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17493                    synchronized (stats) {
17494                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17495                                realtimeSince, wtimeUsed);
17496                    }
17497                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17498                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17499                } else if (doCpuKills && uptimeSince > 0
17500                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17501                    synchronized (stats) {
17502                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17503                                uptimeSince, cputimeUsed);
17504                    }
17505                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17506                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17507                } else {
17508                    app.lastWakeTime = wtime;
17509                    app.lastCpuTime = app.curCpuTime;
17510                }
17511            }
17512        }
17513    }
17514
17515    private final boolean applyOomAdjLocked(ProcessRecord app,
17516            ProcessRecord TOP_APP, boolean doingAll, long now) {
17517        boolean success = true;
17518
17519        if (app.curRawAdj != app.setRawAdj) {
17520            app.setRawAdj = app.curRawAdj;
17521        }
17522
17523        int changes = 0;
17524
17525        if (app.curAdj != app.setAdj) {
17526            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17527            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17528                TAG, "Set " + app.pid + " " + app.processName +
17529                " adj " + app.curAdj + ": " + app.adjType);
17530            app.setAdj = app.curAdj;
17531        }
17532
17533        if (app.setSchedGroup != app.curSchedGroup) {
17534            app.setSchedGroup = app.curSchedGroup;
17535            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17536                    "Setting process group of " + app.processName
17537                    + " to " + app.curSchedGroup);
17538            if (app.waitingToKill != null &&
17539                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17540                app.kill(app.waitingToKill, true);
17541                success = false;
17542            } else {
17543                if (true) {
17544                    long oldId = Binder.clearCallingIdentity();
17545                    try {
17546                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17547                    } catch (Exception e) {
17548                        Slog.w(TAG, "Failed setting process group of " + app.pid
17549                                + " to " + app.curSchedGroup);
17550                        e.printStackTrace();
17551                    } finally {
17552                        Binder.restoreCallingIdentity(oldId);
17553                    }
17554                } else {
17555                    if (app.thread != null) {
17556                        try {
17557                            app.thread.setSchedulingGroup(app.curSchedGroup);
17558                        } catch (RemoteException e) {
17559                        }
17560                    }
17561                }
17562                Process.setSwappiness(app.pid,
17563                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17564            }
17565        }
17566        if (app.repForegroundActivities != app.foregroundActivities) {
17567            app.repForegroundActivities = app.foregroundActivities;
17568            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17569        }
17570        if (app.repProcState != app.curProcState) {
17571            app.repProcState = app.curProcState;
17572            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17573            if (app.thread != null) {
17574                try {
17575                    if (false) {
17576                        //RuntimeException h = new RuntimeException("here");
17577                        Slog.i(TAG, "Sending new process state " + app.repProcState
17578                                + " to " + app /*, h*/);
17579                    }
17580                    app.thread.setProcessState(app.repProcState);
17581                } catch (RemoteException e) {
17582                }
17583            }
17584        }
17585        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17586                app.setProcState)) {
17587            app.lastStateTime = now;
17588            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17589                    isSleeping(), now);
17590            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17591                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17592                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17593                    + (app.nextPssTime-now) + ": " + app);
17594        } else {
17595            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17596                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17597                requestPssLocked(app, app.setProcState);
17598                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17599                        isSleeping(), now);
17600            } else if (false && DEBUG_PSS) {
17601                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17602            }
17603        }
17604        if (app.setProcState != app.curProcState) {
17605            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17606                    "Proc state change of " + app.processName
17607                    + " to " + app.curProcState);
17608            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17609            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17610            if (setImportant && !curImportant) {
17611                // This app is no longer something we consider important enough to allow to
17612                // use arbitrary amounts of battery power.  Note
17613                // its current wake lock time to later know to kill it if
17614                // it is not behaving well.
17615                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17616                synchronized (stats) {
17617                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17618                            app.pid, SystemClock.elapsedRealtime());
17619                }
17620                app.lastCpuTime = app.curCpuTime;
17621
17622            }
17623            app.setProcState = app.curProcState;
17624            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17625                app.notCachedSinceIdle = false;
17626            }
17627            if (!doingAll) {
17628                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17629            } else {
17630                app.procStateChanged = true;
17631            }
17632        }
17633
17634        if (changes != 0) {
17635            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17636            int i = mPendingProcessChanges.size()-1;
17637            ProcessChangeItem item = null;
17638            while (i >= 0) {
17639                item = mPendingProcessChanges.get(i);
17640                if (item.pid == app.pid) {
17641                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17642                    break;
17643                }
17644                i--;
17645            }
17646            if (i < 0) {
17647                // No existing item in pending changes; need a new one.
17648                final int NA = mAvailProcessChanges.size();
17649                if (NA > 0) {
17650                    item = mAvailProcessChanges.remove(NA-1);
17651                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17652                } else {
17653                    item = new ProcessChangeItem();
17654                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17655                }
17656                item.changes = 0;
17657                item.pid = app.pid;
17658                item.uid = app.info.uid;
17659                if (mPendingProcessChanges.size() == 0) {
17660                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17661                            "*** Enqueueing dispatch processes changed!");
17662                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17663                }
17664                mPendingProcessChanges.add(item);
17665            }
17666            item.changes |= changes;
17667            item.processState = app.repProcState;
17668            item.foregroundActivities = app.repForegroundActivities;
17669            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17670                    + Integer.toHexString(System.identityHashCode(item))
17671                    + " " + app.toShortString() + ": changes=" + item.changes
17672                    + " procState=" + item.processState
17673                    + " foreground=" + item.foregroundActivities
17674                    + " type=" + app.adjType + " source=" + app.adjSource
17675                    + " target=" + app.adjTarget);
17676        }
17677
17678        return success;
17679    }
17680
17681    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17682        if (proc.thread != null) {
17683            if (proc.baseProcessTracker != null) {
17684                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17685            }
17686            if (proc.repProcState >= 0) {
17687                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17688                        proc.repProcState);
17689            }
17690        }
17691    }
17692
17693    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17694            ProcessRecord TOP_APP, boolean doingAll, long now) {
17695        if (app.thread == null) {
17696            return false;
17697        }
17698
17699        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17700
17701        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17702    }
17703
17704    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17705            boolean oomAdj) {
17706        if (isForeground != proc.foregroundServices) {
17707            proc.foregroundServices = isForeground;
17708            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17709                    proc.info.uid);
17710            if (isForeground) {
17711                if (curProcs == null) {
17712                    curProcs = new ArrayList<ProcessRecord>();
17713                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17714                }
17715                if (!curProcs.contains(proc)) {
17716                    curProcs.add(proc);
17717                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17718                            proc.info.packageName, proc.info.uid);
17719                }
17720            } else {
17721                if (curProcs != null) {
17722                    if (curProcs.remove(proc)) {
17723                        mBatteryStatsService.noteEvent(
17724                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17725                                proc.info.packageName, proc.info.uid);
17726                        if (curProcs.size() <= 0) {
17727                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17728                        }
17729                    }
17730                }
17731            }
17732            if (oomAdj) {
17733                updateOomAdjLocked();
17734            }
17735        }
17736    }
17737
17738    private final ActivityRecord resumedAppLocked() {
17739        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17740        String pkg;
17741        int uid;
17742        if (act != null) {
17743            pkg = act.packageName;
17744            uid = act.info.applicationInfo.uid;
17745        } else {
17746            pkg = null;
17747            uid = -1;
17748        }
17749        // Has the UID or resumed package name changed?
17750        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17751                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17752            if (mCurResumedPackage != null) {
17753                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17754                        mCurResumedPackage, mCurResumedUid);
17755            }
17756            mCurResumedPackage = pkg;
17757            mCurResumedUid = uid;
17758            if (mCurResumedPackage != null) {
17759                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17760                        mCurResumedPackage, mCurResumedUid);
17761            }
17762        }
17763        return act;
17764    }
17765
17766    final boolean updateOomAdjLocked(ProcessRecord app) {
17767        final ActivityRecord TOP_ACT = resumedAppLocked();
17768        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17769        final boolean wasCached = app.cached;
17770
17771        mAdjSeq++;
17772
17773        // This is the desired cached adjusment we want to tell it to use.
17774        // If our app is currently cached, we know it, and that is it.  Otherwise,
17775        // we don't know it yet, and it needs to now be cached we will then
17776        // need to do a complete oom adj.
17777        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17778                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17779        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17780                SystemClock.uptimeMillis());
17781        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17782            // Changed to/from cached state, so apps after it in the LRU
17783            // list may also be changed.
17784            updateOomAdjLocked();
17785        }
17786        return success;
17787    }
17788
17789    final void updateOomAdjLocked() {
17790        final ActivityRecord TOP_ACT = resumedAppLocked();
17791        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17792        final long now = SystemClock.uptimeMillis();
17793        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17794        final int N = mLruProcesses.size();
17795
17796        if (false) {
17797            RuntimeException e = new RuntimeException();
17798            e.fillInStackTrace();
17799            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17800        }
17801
17802        mAdjSeq++;
17803        mNewNumServiceProcs = 0;
17804        mNewNumAServiceProcs = 0;
17805
17806        final int emptyProcessLimit;
17807        final int cachedProcessLimit;
17808        if (mProcessLimit <= 0) {
17809            emptyProcessLimit = cachedProcessLimit = 0;
17810        } else if (mProcessLimit == 1) {
17811            emptyProcessLimit = 1;
17812            cachedProcessLimit = 0;
17813        } else {
17814            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17815            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17816        }
17817
17818        // Let's determine how many processes we have running vs.
17819        // how many slots we have for background processes; we may want
17820        // to put multiple processes in a slot of there are enough of
17821        // them.
17822        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17823                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17824        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17825        if (numEmptyProcs > cachedProcessLimit) {
17826            // If there are more empty processes than our limit on cached
17827            // processes, then use the cached process limit for the factor.
17828            // This ensures that the really old empty processes get pushed
17829            // down to the bottom, so if we are running low on memory we will
17830            // have a better chance at keeping around more cached processes
17831            // instead of a gazillion empty processes.
17832            numEmptyProcs = cachedProcessLimit;
17833        }
17834        int emptyFactor = numEmptyProcs/numSlots;
17835        if (emptyFactor < 1) emptyFactor = 1;
17836        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17837        if (cachedFactor < 1) cachedFactor = 1;
17838        int stepCached = 0;
17839        int stepEmpty = 0;
17840        int numCached = 0;
17841        int numEmpty = 0;
17842        int numTrimming = 0;
17843
17844        mNumNonCachedProcs = 0;
17845        mNumCachedHiddenProcs = 0;
17846
17847        // First update the OOM adjustment for each of the
17848        // application processes based on their current state.
17849        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17850        int nextCachedAdj = curCachedAdj+1;
17851        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17852        int nextEmptyAdj = curEmptyAdj+2;
17853        for (int i=N-1; i>=0; i--) {
17854            ProcessRecord app = mLruProcesses.get(i);
17855            if (!app.killedByAm && app.thread != null) {
17856                app.procStateChanged = false;
17857                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17858
17859                // If we haven't yet assigned the final cached adj
17860                // to the process, do that now.
17861                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17862                    switch (app.curProcState) {
17863                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17864                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17865                            // This process is a cached process holding activities...
17866                            // assign it the next cached value for that type, and then
17867                            // step that cached level.
17868                            app.curRawAdj = curCachedAdj;
17869                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17870                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17871                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17872                                    + ")");
17873                            if (curCachedAdj != nextCachedAdj) {
17874                                stepCached++;
17875                                if (stepCached >= cachedFactor) {
17876                                    stepCached = 0;
17877                                    curCachedAdj = nextCachedAdj;
17878                                    nextCachedAdj += 2;
17879                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17880                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17881                                    }
17882                                }
17883                            }
17884                            break;
17885                        default:
17886                            // For everything else, assign next empty cached process
17887                            // level and bump that up.  Note that this means that
17888                            // long-running services that have dropped down to the
17889                            // cached level will be treated as empty (since their process
17890                            // state is still as a service), which is what we want.
17891                            app.curRawAdj = curEmptyAdj;
17892                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17893                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17894                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17895                                    + ")");
17896                            if (curEmptyAdj != nextEmptyAdj) {
17897                                stepEmpty++;
17898                                if (stepEmpty >= emptyFactor) {
17899                                    stepEmpty = 0;
17900                                    curEmptyAdj = nextEmptyAdj;
17901                                    nextEmptyAdj += 2;
17902                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17903                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17904                                    }
17905                                }
17906                            }
17907                            break;
17908                    }
17909                }
17910
17911                applyOomAdjLocked(app, TOP_APP, true, now);
17912
17913                // Count the number of process types.
17914                switch (app.curProcState) {
17915                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17916                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17917                        mNumCachedHiddenProcs++;
17918                        numCached++;
17919                        if (numCached > cachedProcessLimit) {
17920                            app.kill("cached #" + numCached, true);
17921                        }
17922                        break;
17923                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17924                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17925                                && app.lastActivityTime < oldTime) {
17926                            app.kill("empty for "
17927                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17928                                    / 1000) + "s", true);
17929                        } else {
17930                            numEmpty++;
17931                            if (numEmpty > emptyProcessLimit) {
17932                                app.kill("empty #" + numEmpty, true);
17933                            }
17934                        }
17935                        break;
17936                    default:
17937                        mNumNonCachedProcs++;
17938                        break;
17939                }
17940
17941                if (app.isolated && app.services.size() <= 0) {
17942                    // If this is an isolated process, and there are no
17943                    // services running in it, then the process is no longer
17944                    // needed.  We agressively kill these because we can by
17945                    // definition not re-use the same process again, and it is
17946                    // good to avoid having whatever code was running in them
17947                    // left sitting around after no longer needed.
17948                    app.kill("isolated not needed", true);
17949                }
17950
17951                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17952                        && !app.killedByAm) {
17953                    numTrimming++;
17954                }
17955            }
17956        }
17957
17958        mNumServiceProcs = mNewNumServiceProcs;
17959
17960        // Now determine the memory trimming level of background processes.
17961        // Unfortunately we need to start at the back of the list to do this
17962        // properly.  We only do this if the number of background apps we
17963        // are managing to keep around is less than half the maximum we desire;
17964        // if we are keeping a good number around, we'll let them use whatever
17965        // memory they want.
17966        final int numCachedAndEmpty = numCached + numEmpty;
17967        int memFactor;
17968        if (numCached <= ProcessList.TRIM_CACHED_APPS
17969                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17970            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17971                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17972            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17973                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17974            } else {
17975                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17976            }
17977        } else {
17978            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17979        }
17980        // We always allow the memory level to go up (better).  We only allow it to go
17981        // down if we are in a state where that is allowed, *and* the total number of processes
17982        // has gone down since last time.
17983        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17984                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17985                + " last=" + mLastNumProcesses);
17986        if (memFactor > mLastMemoryLevel) {
17987            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17988                memFactor = mLastMemoryLevel;
17989                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17990            }
17991        }
17992        mLastMemoryLevel = memFactor;
17993        mLastNumProcesses = mLruProcesses.size();
17994        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17995        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17996        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17997            if (mLowRamStartTime == 0) {
17998                mLowRamStartTime = now;
17999            }
18000            int step = 0;
18001            int fgTrimLevel;
18002            switch (memFactor) {
18003                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18004                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18005                    break;
18006                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18007                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18008                    break;
18009                default:
18010                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18011                    break;
18012            }
18013            int factor = numTrimming/3;
18014            int minFactor = 2;
18015            if (mHomeProcess != null) minFactor++;
18016            if (mPreviousProcess != null) minFactor++;
18017            if (factor < minFactor) factor = minFactor;
18018            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18019            for (int i=N-1; i>=0; i--) {
18020                ProcessRecord app = mLruProcesses.get(i);
18021                if (allChanged || app.procStateChanged) {
18022                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18023                    app.procStateChanged = false;
18024                }
18025                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18026                        && !app.killedByAm) {
18027                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18028                        try {
18029                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18030                                    "Trimming memory of " + app.processName
18031                                    + " to " + curLevel);
18032                            app.thread.scheduleTrimMemory(curLevel);
18033                        } catch (RemoteException e) {
18034                        }
18035                        if (false) {
18036                            // For now we won't do this; our memory trimming seems
18037                            // to be good enough at this point that destroying
18038                            // activities causes more harm than good.
18039                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18040                                    && app != mHomeProcess && app != mPreviousProcess) {
18041                                // Need to do this on its own message because the stack may not
18042                                // be in a consistent state at this point.
18043                                // For these apps we will also finish their activities
18044                                // to help them free memory.
18045                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18046                            }
18047                        }
18048                    }
18049                    app.trimMemoryLevel = curLevel;
18050                    step++;
18051                    if (step >= factor) {
18052                        step = 0;
18053                        switch (curLevel) {
18054                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18055                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18056                                break;
18057                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18058                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18059                                break;
18060                        }
18061                    }
18062                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18063                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18064                            && app.thread != null) {
18065                        try {
18066                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18067                                    "Trimming memory of heavy-weight " + app.processName
18068                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18069                            app.thread.scheduleTrimMemory(
18070                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18071                        } catch (RemoteException e) {
18072                        }
18073                    }
18074                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18075                } else {
18076                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18077                            || app.systemNoUi) && app.pendingUiClean) {
18078                        // If this application is now in the background and it
18079                        // had done UI, then give it the special trim level to
18080                        // have it free UI resources.
18081                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18082                        if (app.trimMemoryLevel < level && app.thread != null) {
18083                            try {
18084                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18085                                        "Trimming memory of bg-ui " + app.processName
18086                                        + " to " + level);
18087                                app.thread.scheduleTrimMemory(level);
18088                            } catch (RemoteException e) {
18089                            }
18090                        }
18091                        app.pendingUiClean = false;
18092                    }
18093                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18094                        try {
18095                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18096                                    "Trimming memory of fg " + app.processName
18097                                    + " to " + fgTrimLevel);
18098                            app.thread.scheduleTrimMemory(fgTrimLevel);
18099                        } catch (RemoteException e) {
18100                        }
18101                    }
18102                    app.trimMemoryLevel = fgTrimLevel;
18103                }
18104            }
18105        } else {
18106            if (mLowRamStartTime != 0) {
18107                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18108                mLowRamStartTime = 0;
18109            }
18110            for (int i=N-1; i>=0; i--) {
18111                ProcessRecord app = mLruProcesses.get(i);
18112                if (allChanged || app.procStateChanged) {
18113                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18114                    app.procStateChanged = false;
18115                }
18116                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18117                        || app.systemNoUi) && app.pendingUiClean) {
18118                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18119                            && app.thread != null) {
18120                        try {
18121                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18122                                    "Trimming memory of ui hidden " + app.processName
18123                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18124                            app.thread.scheduleTrimMemory(
18125                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18126                        } catch (RemoteException e) {
18127                        }
18128                    }
18129                    app.pendingUiClean = false;
18130                }
18131                app.trimMemoryLevel = 0;
18132            }
18133        }
18134
18135        if (mAlwaysFinishActivities) {
18136            // Need to do this on its own message because the stack may not
18137            // be in a consistent state at this point.
18138            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18139        }
18140
18141        if (allChanged) {
18142            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18143        }
18144
18145        if (mProcessStats.shouldWriteNowLocked(now)) {
18146            mHandler.post(new Runnable() {
18147                @Override public void run() {
18148                    synchronized (ActivityManagerService.this) {
18149                        mProcessStats.writeStateAsyncLocked();
18150                    }
18151                }
18152            });
18153        }
18154
18155        if (DEBUG_OOM_ADJ) {
18156            if (false) {
18157                RuntimeException here = new RuntimeException("here");
18158                here.fillInStackTrace();
18159                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18160            } else {
18161                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18162            }
18163        }
18164    }
18165
18166    final void trimApplications() {
18167        synchronized (this) {
18168            int i;
18169
18170            // First remove any unused application processes whose package
18171            // has been removed.
18172            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18173                final ProcessRecord app = mRemovedProcesses.get(i);
18174                if (app.activities.size() == 0
18175                        && app.curReceiver == null && app.services.size() == 0) {
18176                    Slog.i(
18177                        TAG, "Exiting empty application process "
18178                        + app.processName + " ("
18179                        + (app.thread != null ? app.thread.asBinder() : null)
18180                        + ")\n");
18181                    if (app.pid > 0 && app.pid != MY_PID) {
18182                        app.kill("empty", false);
18183                    } else {
18184                        try {
18185                            app.thread.scheduleExit();
18186                        } catch (Exception e) {
18187                            // Ignore exceptions.
18188                        }
18189                    }
18190                    cleanUpApplicationRecordLocked(app, false, true, -1);
18191                    mRemovedProcesses.remove(i);
18192
18193                    if (app.persistent) {
18194                        addAppLocked(app.info, false, null /* ABI override */);
18195                    }
18196                }
18197            }
18198
18199            // Now update the oom adj for all processes.
18200            updateOomAdjLocked();
18201        }
18202    }
18203
18204    /** This method sends the specified signal to each of the persistent apps */
18205    public void signalPersistentProcesses(int sig) throws RemoteException {
18206        if (sig != Process.SIGNAL_USR1) {
18207            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18208        }
18209
18210        synchronized (this) {
18211            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18212                    != PackageManager.PERMISSION_GRANTED) {
18213                throw new SecurityException("Requires permission "
18214                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18215            }
18216
18217            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18218                ProcessRecord r = mLruProcesses.get(i);
18219                if (r.thread != null && r.persistent) {
18220                    Process.sendSignal(r.pid, sig);
18221                }
18222            }
18223        }
18224    }
18225
18226    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18227        if (proc == null || proc == mProfileProc) {
18228            proc = mProfileProc;
18229            profileType = mProfileType;
18230            clearProfilerLocked();
18231        }
18232        if (proc == null) {
18233            return;
18234        }
18235        try {
18236            proc.thread.profilerControl(false, null, profileType);
18237        } catch (RemoteException e) {
18238            throw new IllegalStateException("Process disappeared");
18239        }
18240    }
18241
18242    private void clearProfilerLocked() {
18243        if (mProfileFd != null) {
18244            try {
18245                mProfileFd.close();
18246            } catch (IOException e) {
18247            }
18248        }
18249        mProfileApp = null;
18250        mProfileProc = null;
18251        mProfileFile = null;
18252        mProfileType = 0;
18253        mAutoStopProfiler = false;
18254        mSamplingInterval = 0;
18255    }
18256
18257    public boolean profileControl(String process, int userId, boolean start,
18258            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18259
18260        try {
18261            synchronized (this) {
18262                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18263                // its own permission.
18264                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18265                        != PackageManager.PERMISSION_GRANTED) {
18266                    throw new SecurityException("Requires permission "
18267                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18268                }
18269
18270                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18271                    throw new IllegalArgumentException("null profile info or fd");
18272                }
18273
18274                ProcessRecord proc = null;
18275                if (process != null) {
18276                    proc = findProcessLocked(process, userId, "profileControl");
18277                }
18278
18279                if (start && (proc == null || proc.thread == null)) {
18280                    throw new IllegalArgumentException("Unknown process: " + process);
18281                }
18282
18283                if (start) {
18284                    stopProfilerLocked(null, 0);
18285                    setProfileApp(proc.info, proc.processName, profilerInfo);
18286                    mProfileProc = proc;
18287                    mProfileType = profileType;
18288                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18289                    try {
18290                        fd = fd.dup();
18291                    } catch (IOException e) {
18292                        fd = null;
18293                    }
18294                    profilerInfo.profileFd = fd;
18295                    proc.thread.profilerControl(start, profilerInfo, profileType);
18296                    fd = null;
18297                    mProfileFd = null;
18298                } else {
18299                    stopProfilerLocked(proc, profileType);
18300                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18301                        try {
18302                            profilerInfo.profileFd.close();
18303                        } catch (IOException e) {
18304                        }
18305                    }
18306                }
18307
18308                return true;
18309            }
18310        } catch (RemoteException e) {
18311            throw new IllegalStateException("Process disappeared");
18312        } finally {
18313            if (profilerInfo != null && profilerInfo.profileFd != null) {
18314                try {
18315                    profilerInfo.profileFd.close();
18316                } catch (IOException e) {
18317                }
18318            }
18319        }
18320    }
18321
18322    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18323        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18324                userId, true, ALLOW_FULL_ONLY, callName, null);
18325        ProcessRecord proc = null;
18326        try {
18327            int pid = Integer.parseInt(process);
18328            synchronized (mPidsSelfLocked) {
18329                proc = mPidsSelfLocked.get(pid);
18330            }
18331        } catch (NumberFormatException e) {
18332        }
18333
18334        if (proc == null) {
18335            ArrayMap<String, SparseArray<ProcessRecord>> all
18336                    = mProcessNames.getMap();
18337            SparseArray<ProcessRecord> procs = all.get(process);
18338            if (procs != null && procs.size() > 0) {
18339                proc = procs.valueAt(0);
18340                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18341                    for (int i=1; i<procs.size(); i++) {
18342                        ProcessRecord thisProc = procs.valueAt(i);
18343                        if (thisProc.userId == userId) {
18344                            proc = thisProc;
18345                            break;
18346                        }
18347                    }
18348                }
18349            }
18350        }
18351
18352        return proc;
18353    }
18354
18355    public boolean dumpHeap(String process, int userId, boolean managed,
18356            String path, ParcelFileDescriptor fd) throws RemoteException {
18357
18358        try {
18359            synchronized (this) {
18360                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18361                // its own permission (same as profileControl).
18362                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18363                        != PackageManager.PERMISSION_GRANTED) {
18364                    throw new SecurityException("Requires permission "
18365                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18366                }
18367
18368                if (fd == null) {
18369                    throw new IllegalArgumentException("null fd");
18370                }
18371
18372                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18373                if (proc == null || proc.thread == null) {
18374                    throw new IllegalArgumentException("Unknown process: " + process);
18375                }
18376
18377                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18378                if (!isDebuggable) {
18379                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18380                        throw new SecurityException("Process not debuggable: " + proc);
18381                    }
18382                }
18383
18384                proc.thread.dumpHeap(managed, path, fd);
18385                fd = null;
18386                return true;
18387            }
18388        } catch (RemoteException e) {
18389            throw new IllegalStateException("Process disappeared");
18390        } finally {
18391            if (fd != null) {
18392                try {
18393                    fd.close();
18394                } catch (IOException e) {
18395                }
18396            }
18397        }
18398    }
18399
18400    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18401    public void monitor() {
18402        synchronized (this) { }
18403    }
18404
18405    void onCoreSettingsChange(Bundle settings) {
18406        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18407            ProcessRecord processRecord = mLruProcesses.get(i);
18408            try {
18409                if (processRecord.thread != null) {
18410                    processRecord.thread.setCoreSettings(settings);
18411                }
18412            } catch (RemoteException re) {
18413                /* ignore */
18414            }
18415        }
18416    }
18417
18418    // Multi-user methods
18419
18420    /**
18421     * Start user, if its not already running, but don't bring it to foreground.
18422     */
18423    @Override
18424    public boolean startUserInBackground(final int userId) {
18425        return startUser(userId, /* foreground */ false);
18426    }
18427
18428    /**
18429     * Start user, if its not already running, and bring it to foreground.
18430     */
18431    boolean startUserInForeground(final int userId, Dialog dlg) {
18432        boolean result = startUser(userId, /* foreground */ true);
18433        dlg.dismiss();
18434        return result;
18435    }
18436
18437    /**
18438     * Refreshes the list of users related to the current user when either a
18439     * user switch happens or when a new related user is started in the
18440     * background.
18441     */
18442    private void updateCurrentProfileIdsLocked() {
18443        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18444                mCurrentUserId, false /* enabledOnly */);
18445        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18446        for (int i = 0; i < currentProfileIds.length; i++) {
18447            currentProfileIds[i] = profiles.get(i).id;
18448        }
18449        mCurrentProfileIds = currentProfileIds;
18450
18451        synchronized (mUserProfileGroupIdsSelfLocked) {
18452            mUserProfileGroupIdsSelfLocked.clear();
18453            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18454            for (int i = 0; i < users.size(); i++) {
18455                UserInfo user = users.get(i);
18456                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18457                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18458                }
18459            }
18460        }
18461    }
18462
18463    private Set getProfileIdsLocked(int userId) {
18464        Set userIds = new HashSet<Integer>();
18465        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18466                userId, false /* enabledOnly */);
18467        for (UserInfo user : profiles) {
18468            userIds.add(Integer.valueOf(user.id));
18469        }
18470        return userIds;
18471    }
18472
18473    @Override
18474    public boolean switchUser(final int userId) {
18475        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18476        String userName;
18477        synchronized (this) {
18478            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18479            if (userInfo == null) {
18480                Slog.w(TAG, "No user info for user #" + userId);
18481                return false;
18482            }
18483            if (userInfo.isManagedProfile()) {
18484                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18485                return false;
18486            }
18487            userName = userInfo.name;
18488            mTargetUserId = userId;
18489        }
18490        mHandler.removeMessages(START_USER_SWITCH_MSG);
18491        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18492        return true;
18493    }
18494
18495    private void showUserSwitchDialog(int userId, String userName) {
18496        // The dialog will show and then initiate the user switch by calling startUserInForeground
18497        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18498                true /* above system */);
18499        d.show();
18500    }
18501
18502    private boolean startUser(final int userId, final boolean foreground) {
18503        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18504                != PackageManager.PERMISSION_GRANTED) {
18505            String msg = "Permission Denial: switchUser() from pid="
18506                    + Binder.getCallingPid()
18507                    + ", uid=" + Binder.getCallingUid()
18508                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18509            Slog.w(TAG, msg);
18510            throw new SecurityException(msg);
18511        }
18512
18513        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18514
18515        final long ident = Binder.clearCallingIdentity();
18516        try {
18517            synchronized (this) {
18518                final int oldUserId = mCurrentUserId;
18519                if (oldUserId == userId) {
18520                    return true;
18521                }
18522
18523                mStackSupervisor.setLockTaskModeLocked(null, false);
18524
18525                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18526                if (userInfo == null) {
18527                    Slog.w(TAG, "No user info for user #" + userId);
18528                    return false;
18529                }
18530                if (foreground && userInfo.isManagedProfile()) {
18531                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18532                    return false;
18533                }
18534
18535                if (foreground) {
18536                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18537                            R.anim.screen_user_enter);
18538                }
18539
18540                boolean needStart = false;
18541
18542                // If the user we are switching to is not currently started, then
18543                // we need to start it now.
18544                if (mStartedUsers.get(userId) == null) {
18545                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18546                    updateStartedUserArrayLocked();
18547                    needStart = true;
18548                }
18549
18550                final Integer userIdInt = Integer.valueOf(userId);
18551                mUserLru.remove(userIdInt);
18552                mUserLru.add(userIdInt);
18553
18554                if (foreground) {
18555                    mCurrentUserId = userId;
18556                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18557                    updateCurrentProfileIdsLocked();
18558                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18559                    // Once the internal notion of the active user has switched, we lock the device
18560                    // with the option to show the user switcher on the keyguard.
18561                    mWindowManager.lockNow(null);
18562                } else {
18563                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18564                    updateCurrentProfileIdsLocked();
18565                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18566                    mUserLru.remove(currentUserIdInt);
18567                    mUserLru.add(currentUserIdInt);
18568                }
18569
18570                final UserStartedState uss = mStartedUsers.get(userId);
18571
18572                // Make sure user is in the started state.  If it is currently
18573                // stopping, we need to knock that off.
18574                if (uss.mState == UserStartedState.STATE_STOPPING) {
18575                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18576                    // so we can just fairly silently bring the user back from
18577                    // the almost-dead.
18578                    uss.mState = UserStartedState.STATE_RUNNING;
18579                    updateStartedUserArrayLocked();
18580                    needStart = true;
18581                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18582                    // This means ACTION_SHUTDOWN has been sent, so we will
18583                    // need to treat this as a new boot of the user.
18584                    uss.mState = UserStartedState.STATE_BOOTING;
18585                    updateStartedUserArrayLocked();
18586                    needStart = true;
18587                }
18588
18589                if (uss.mState == UserStartedState.STATE_BOOTING) {
18590                    // Booting up a new user, need to tell system services about it.
18591                    // Note that this is on the same handler as scheduling of broadcasts,
18592                    // which is important because it needs to go first.
18593                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18594                }
18595
18596                if (foreground) {
18597                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18598                            oldUserId));
18599                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18600                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18601                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18602                            oldUserId, userId, uss));
18603                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18604                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18605                }
18606
18607                if (needStart) {
18608                    // Send USER_STARTED broadcast
18609                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18610                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18611                            | Intent.FLAG_RECEIVER_FOREGROUND);
18612                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18613                    broadcastIntentLocked(null, null, intent,
18614                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18615                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18616                }
18617
18618                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18619                    if (userId != UserHandle.USER_OWNER) {
18620                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18621                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18622                        broadcastIntentLocked(null, null, intent, null,
18623                                new IIntentReceiver.Stub() {
18624                                    public void performReceive(Intent intent, int resultCode,
18625                                            String data, Bundle extras, boolean ordered,
18626                                            boolean sticky, int sendingUser) {
18627                                        onUserInitialized(uss, foreground, oldUserId, userId);
18628                                    }
18629                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18630                                true, false, MY_PID, Process.SYSTEM_UID,
18631                                userId);
18632                        uss.initializing = true;
18633                    } else {
18634                        getUserManagerLocked().makeInitialized(userInfo.id);
18635                    }
18636                }
18637
18638                if (foreground) {
18639                    if (!uss.initializing) {
18640                        moveUserToForeground(uss, oldUserId, userId);
18641                    }
18642                } else {
18643                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18644                }
18645
18646                if (needStart) {
18647                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18648                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18649                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18650                    broadcastIntentLocked(null, null, intent,
18651                            null, new IIntentReceiver.Stub() {
18652                                @Override
18653                                public void performReceive(Intent intent, int resultCode, String data,
18654                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18655                                        throws RemoteException {
18656                                }
18657                            }, 0, null, null,
18658                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18659                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18660                }
18661            }
18662        } finally {
18663            Binder.restoreCallingIdentity(ident);
18664        }
18665
18666        return true;
18667    }
18668
18669    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18670        long ident = Binder.clearCallingIdentity();
18671        try {
18672            Intent intent;
18673            if (oldUserId >= 0) {
18674                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18675                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18676                int count = profiles.size();
18677                for (int i = 0; i < count; i++) {
18678                    int profileUserId = profiles.get(i).id;
18679                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18680                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18681                            | Intent.FLAG_RECEIVER_FOREGROUND);
18682                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18683                    broadcastIntentLocked(null, null, intent,
18684                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18685                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18686                }
18687            }
18688            if (newUserId >= 0) {
18689                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18690                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18691                int count = profiles.size();
18692                for (int i = 0; i < count; i++) {
18693                    int profileUserId = profiles.get(i).id;
18694                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18695                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18696                            | Intent.FLAG_RECEIVER_FOREGROUND);
18697                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18698                    broadcastIntentLocked(null, null, intent,
18699                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18700                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18701                }
18702                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18703                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18704                        | Intent.FLAG_RECEIVER_FOREGROUND);
18705                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18706                broadcastIntentLocked(null, null, intent,
18707                        null, null, 0, null, null,
18708                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18709                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18710            }
18711        } finally {
18712            Binder.restoreCallingIdentity(ident);
18713        }
18714    }
18715
18716    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18717            final int newUserId) {
18718        final int N = mUserSwitchObservers.beginBroadcast();
18719        if (N > 0) {
18720            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18721                int mCount = 0;
18722                @Override
18723                public void sendResult(Bundle data) throws RemoteException {
18724                    synchronized (ActivityManagerService.this) {
18725                        if (mCurUserSwitchCallback == this) {
18726                            mCount++;
18727                            if (mCount == N) {
18728                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18729                            }
18730                        }
18731                    }
18732                }
18733            };
18734            synchronized (this) {
18735                uss.switching = true;
18736                mCurUserSwitchCallback = callback;
18737            }
18738            for (int i=0; i<N; i++) {
18739                try {
18740                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18741                            newUserId, callback);
18742                } catch (RemoteException e) {
18743                }
18744            }
18745        } else {
18746            synchronized (this) {
18747                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18748            }
18749        }
18750        mUserSwitchObservers.finishBroadcast();
18751    }
18752
18753    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18754        synchronized (this) {
18755            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18756            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18757        }
18758    }
18759
18760    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18761        mCurUserSwitchCallback = null;
18762        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18763        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18764                oldUserId, newUserId, uss));
18765    }
18766
18767    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18768        synchronized (this) {
18769            if (foreground) {
18770                moveUserToForeground(uss, oldUserId, newUserId);
18771            }
18772        }
18773
18774        completeSwitchAndInitalize(uss, newUserId, true, false);
18775    }
18776
18777    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18778        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18779        if (homeInFront) {
18780            startHomeActivityLocked(newUserId);
18781        } else {
18782            mStackSupervisor.resumeTopActivitiesLocked();
18783        }
18784        EventLogTags.writeAmSwitchUser(newUserId);
18785        getUserManagerLocked().userForeground(newUserId);
18786        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18787    }
18788
18789    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18790        completeSwitchAndInitalize(uss, newUserId, false, true);
18791    }
18792
18793    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18794            boolean clearInitializing, boolean clearSwitching) {
18795        boolean unfrozen = false;
18796        synchronized (this) {
18797            if (clearInitializing) {
18798                uss.initializing = false;
18799                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18800            }
18801            if (clearSwitching) {
18802                uss.switching = false;
18803            }
18804            if (!uss.switching && !uss.initializing) {
18805                mWindowManager.stopFreezingScreen();
18806                unfrozen = true;
18807            }
18808        }
18809        if (unfrozen) {
18810            final int N = mUserSwitchObservers.beginBroadcast();
18811            for (int i=0; i<N; i++) {
18812                try {
18813                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18814                } catch (RemoteException e) {
18815                }
18816            }
18817            mUserSwitchObservers.finishBroadcast();
18818        }
18819    }
18820
18821    void scheduleStartProfilesLocked() {
18822        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18823            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18824                    DateUtils.SECOND_IN_MILLIS);
18825        }
18826    }
18827
18828    void startProfilesLocked() {
18829        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18830        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18831                mCurrentUserId, false /* enabledOnly */);
18832        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18833        for (UserInfo user : profiles) {
18834            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18835                    && user.id != mCurrentUserId) {
18836                toStart.add(user);
18837            }
18838        }
18839        final int n = toStart.size();
18840        int i = 0;
18841        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18842            startUserInBackground(toStart.get(i).id);
18843        }
18844        if (i < n) {
18845            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18846        }
18847    }
18848
18849    void finishUserBoot(UserStartedState uss) {
18850        synchronized (this) {
18851            if (uss.mState == UserStartedState.STATE_BOOTING
18852                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18853                uss.mState = UserStartedState.STATE_RUNNING;
18854                final int userId = uss.mHandle.getIdentifier();
18855                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18856                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18857                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18858                broadcastIntentLocked(null, null, intent,
18859                        null, null, 0, null, null,
18860                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18861                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18862            }
18863        }
18864    }
18865
18866    void finishUserSwitch(UserStartedState uss) {
18867        synchronized (this) {
18868            finishUserBoot(uss);
18869
18870            startProfilesLocked();
18871
18872            int num = mUserLru.size();
18873            int i = 0;
18874            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18875                Integer oldUserId = mUserLru.get(i);
18876                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18877                if (oldUss == null) {
18878                    // Shouldn't happen, but be sane if it does.
18879                    mUserLru.remove(i);
18880                    num--;
18881                    continue;
18882                }
18883                if (oldUss.mState == UserStartedState.STATE_STOPPING
18884                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18885                    // This user is already stopping, doesn't count.
18886                    num--;
18887                    i++;
18888                    continue;
18889                }
18890                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18891                    // Owner and current can't be stopped, but count as running.
18892                    i++;
18893                    continue;
18894                }
18895                // This is a user to be stopped.
18896                stopUserLocked(oldUserId, null);
18897                num--;
18898                i++;
18899            }
18900        }
18901    }
18902
18903    @Override
18904    public int stopUser(final int userId, final IStopUserCallback callback) {
18905        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18906                != PackageManager.PERMISSION_GRANTED) {
18907            String msg = "Permission Denial: switchUser() from pid="
18908                    + Binder.getCallingPid()
18909                    + ", uid=" + Binder.getCallingUid()
18910                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18911            Slog.w(TAG, msg);
18912            throw new SecurityException(msg);
18913        }
18914        if (userId <= 0) {
18915            throw new IllegalArgumentException("Can't stop primary user " + userId);
18916        }
18917        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18918        synchronized (this) {
18919            return stopUserLocked(userId, callback);
18920        }
18921    }
18922
18923    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18924        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18925        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18926            return ActivityManager.USER_OP_IS_CURRENT;
18927        }
18928
18929        final UserStartedState uss = mStartedUsers.get(userId);
18930        if (uss == null) {
18931            // User is not started, nothing to do...  but we do need to
18932            // callback if requested.
18933            if (callback != null) {
18934                mHandler.post(new Runnable() {
18935                    @Override
18936                    public void run() {
18937                        try {
18938                            callback.userStopped(userId);
18939                        } catch (RemoteException e) {
18940                        }
18941                    }
18942                });
18943            }
18944            return ActivityManager.USER_OP_SUCCESS;
18945        }
18946
18947        if (callback != null) {
18948            uss.mStopCallbacks.add(callback);
18949        }
18950
18951        if (uss.mState != UserStartedState.STATE_STOPPING
18952                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18953            uss.mState = UserStartedState.STATE_STOPPING;
18954            updateStartedUserArrayLocked();
18955
18956            long ident = Binder.clearCallingIdentity();
18957            try {
18958                // We are going to broadcast ACTION_USER_STOPPING and then
18959                // once that is done send a final ACTION_SHUTDOWN and then
18960                // stop the user.
18961                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18962                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18963                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18964                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18965                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18966                // This is the result receiver for the final shutdown broadcast.
18967                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18968                    @Override
18969                    public void performReceive(Intent intent, int resultCode, String data,
18970                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18971                        finishUserStop(uss);
18972                    }
18973                };
18974                // This is the result receiver for the initial stopping broadcast.
18975                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18976                    @Override
18977                    public void performReceive(Intent intent, int resultCode, String data,
18978                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18979                        // On to the next.
18980                        synchronized (ActivityManagerService.this) {
18981                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18982                                // Whoops, we are being started back up.  Abort, abort!
18983                                return;
18984                            }
18985                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18986                        }
18987                        mBatteryStatsService.noteEvent(
18988                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18989                                Integer.toString(userId), userId);
18990                        mSystemServiceManager.stopUser(userId);
18991                        broadcastIntentLocked(null, null, shutdownIntent,
18992                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18993                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18994                    }
18995                };
18996                // Kick things off.
18997                broadcastIntentLocked(null, null, stoppingIntent,
18998                        null, stoppingReceiver, 0, null, null,
18999                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19000                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19001            } finally {
19002                Binder.restoreCallingIdentity(ident);
19003            }
19004        }
19005
19006        return ActivityManager.USER_OP_SUCCESS;
19007    }
19008
19009    void finishUserStop(UserStartedState uss) {
19010        final int userId = uss.mHandle.getIdentifier();
19011        boolean stopped;
19012        ArrayList<IStopUserCallback> callbacks;
19013        synchronized (this) {
19014            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19015            if (mStartedUsers.get(userId) != uss) {
19016                stopped = false;
19017            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19018                stopped = false;
19019            } else {
19020                stopped = true;
19021                // User can no longer run.
19022                mStartedUsers.remove(userId);
19023                mUserLru.remove(Integer.valueOf(userId));
19024                updateStartedUserArrayLocked();
19025
19026                // Clean up all state and processes associated with the user.
19027                // Kill all the processes for the user.
19028                forceStopUserLocked(userId, "finish user");
19029            }
19030
19031            // Explicitly remove the old information in mRecentTasks.
19032            removeRecentTasksForUserLocked(userId);
19033        }
19034
19035        for (int i=0; i<callbacks.size(); i++) {
19036            try {
19037                if (stopped) callbacks.get(i).userStopped(userId);
19038                else callbacks.get(i).userStopAborted(userId);
19039            } catch (RemoteException e) {
19040            }
19041        }
19042
19043        if (stopped) {
19044            mSystemServiceManager.cleanupUser(userId);
19045            synchronized (this) {
19046                mStackSupervisor.removeUserLocked(userId);
19047            }
19048        }
19049    }
19050
19051    @Override
19052    public UserInfo getCurrentUser() {
19053        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19054                != PackageManager.PERMISSION_GRANTED) && (
19055                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19056                != PackageManager.PERMISSION_GRANTED)) {
19057            String msg = "Permission Denial: getCurrentUser() from pid="
19058                    + Binder.getCallingPid()
19059                    + ", uid=" + Binder.getCallingUid()
19060                    + " requires " + INTERACT_ACROSS_USERS;
19061            Slog.w(TAG, msg);
19062            throw new SecurityException(msg);
19063        }
19064        synchronized (this) {
19065            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19066            return getUserManagerLocked().getUserInfo(userId);
19067        }
19068    }
19069
19070    int getCurrentUserIdLocked() {
19071        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19072    }
19073
19074    @Override
19075    public boolean isUserRunning(int userId, boolean orStopped) {
19076        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19077                != PackageManager.PERMISSION_GRANTED) {
19078            String msg = "Permission Denial: isUserRunning() from pid="
19079                    + Binder.getCallingPid()
19080                    + ", uid=" + Binder.getCallingUid()
19081                    + " requires " + INTERACT_ACROSS_USERS;
19082            Slog.w(TAG, msg);
19083            throw new SecurityException(msg);
19084        }
19085        synchronized (this) {
19086            return isUserRunningLocked(userId, orStopped);
19087        }
19088    }
19089
19090    boolean isUserRunningLocked(int userId, boolean orStopped) {
19091        UserStartedState state = mStartedUsers.get(userId);
19092        if (state == null) {
19093            return false;
19094        }
19095        if (orStopped) {
19096            return true;
19097        }
19098        return state.mState != UserStartedState.STATE_STOPPING
19099                && state.mState != UserStartedState.STATE_SHUTDOWN;
19100    }
19101
19102    @Override
19103    public int[] getRunningUserIds() {
19104        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19105                != PackageManager.PERMISSION_GRANTED) {
19106            String msg = "Permission Denial: isUserRunning() from pid="
19107                    + Binder.getCallingPid()
19108                    + ", uid=" + Binder.getCallingUid()
19109                    + " requires " + INTERACT_ACROSS_USERS;
19110            Slog.w(TAG, msg);
19111            throw new SecurityException(msg);
19112        }
19113        synchronized (this) {
19114            return mStartedUserArray;
19115        }
19116    }
19117
19118    private void updateStartedUserArrayLocked() {
19119        int num = 0;
19120        for (int i=0; i<mStartedUsers.size();  i++) {
19121            UserStartedState uss = mStartedUsers.valueAt(i);
19122            // This list does not include stopping users.
19123            if (uss.mState != UserStartedState.STATE_STOPPING
19124                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19125                num++;
19126            }
19127        }
19128        mStartedUserArray = new int[num];
19129        num = 0;
19130        for (int i=0; i<mStartedUsers.size();  i++) {
19131            UserStartedState uss = mStartedUsers.valueAt(i);
19132            if (uss.mState != UserStartedState.STATE_STOPPING
19133                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19134                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19135                num++;
19136            }
19137        }
19138    }
19139
19140    @Override
19141    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19142        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19143                != PackageManager.PERMISSION_GRANTED) {
19144            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19145                    + Binder.getCallingPid()
19146                    + ", uid=" + Binder.getCallingUid()
19147                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19148            Slog.w(TAG, msg);
19149            throw new SecurityException(msg);
19150        }
19151
19152        mUserSwitchObservers.register(observer);
19153    }
19154
19155    @Override
19156    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19157        mUserSwitchObservers.unregister(observer);
19158    }
19159
19160    private boolean userExists(int userId) {
19161        if (userId == 0) {
19162            return true;
19163        }
19164        UserManagerService ums = getUserManagerLocked();
19165        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19166    }
19167
19168    int[] getUsersLocked() {
19169        UserManagerService ums = getUserManagerLocked();
19170        return ums != null ? ums.getUserIds() : new int[] { 0 };
19171    }
19172
19173    UserManagerService getUserManagerLocked() {
19174        if (mUserManager == null) {
19175            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19176            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19177        }
19178        return mUserManager;
19179    }
19180
19181    private int applyUserId(int uid, int userId) {
19182        return UserHandle.getUid(userId, uid);
19183    }
19184
19185    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19186        if (info == null) return null;
19187        ApplicationInfo newInfo = new ApplicationInfo(info);
19188        newInfo.uid = applyUserId(info.uid, userId);
19189        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19190                + info.packageName;
19191        return newInfo;
19192    }
19193
19194    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19195        if (aInfo == null
19196                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19197            return aInfo;
19198        }
19199
19200        ActivityInfo info = new ActivityInfo(aInfo);
19201        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19202        return info;
19203    }
19204
19205    private final class LocalService extends ActivityManagerInternal {
19206        @Override
19207        public void goingToSleep() {
19208            ActivityManagerService.this.goingToSleep();
19209        }
19210
19211        @Override
19212        public void wakingUp() {
19213            ActivityManagerService.this.wakingUp();
19214        }
19215
19216        @Override
19217        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19218                String processName, String abiOverride, int uid, Runnable crashHandler) {
19219            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19220                    processName, abiOverride, uid, crashHandler);
19221        }
19222    }
19223
19224    /**
19225     * An implementation of IAppTask, that allows an app to manage its own tasks via
19226     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19227     * only the process that calls getAppTasks() can call the AppTask methods.
19228     */
19229    class AppTaskImpl extends IAppTask.Stub {
19230        private int mTaskId;
19231        private int mCallingUid;
19232
19233        public AppTaskImpl(int taskId, int callingUid) {
19234            mTaskId = taskId;
19235            mCallingUid = callingUid;
19236        }
19237
19238        private void checkCaller() {
19239            if (mCallingUid != Binder.getCallingUid()) {
19240                throw new SecurityException("Caller " + mCallingUid
19241                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19242            }
19243        }
19244
19245        @Override
19246        public void finishAndRemoveTask() {
19247            checkCaller();
19248
19249            synchronized (ActivityManagerService.this) {
19250                long origId = Binder.clearCallingIdentity();
19251                try {
19252                    if (!removeTaskByIdLocked(mTaskId, false)) {
19253                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19254                    }
19255                } finally {
19256                    Binder.restoreCallingIdentity(origId);
19257                }
19258            }
19259        }
19260
19261        @Override
19262        public ActivityManager.RecentTaskInfo getTaskInfo() {
19263            checkCaller();
19264
19265            synchronized (ActivityManagerService.this) {
19266                long origId = Binder.clearCallingIdentity();
19267                try {
19268                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19269                    if (tr == null) {
19270                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19271                    }
19272                    return createRecentTaskInfoFromTaskRecord(tr);
19273                } finally {
19274                    Binder.restoreCallingIdentity(origId);
19275                }
19276            }
19277        }
19278
19279        @Override
19280        public void moveToFront() {
19281            checkCaller();
19282
19283            final TaskRecord tr;
19284            synchronized (ActivityManagerService.this) {
19285                tr = recentTaskForIdLocked(mTaskId);
19286                if (tr == null) {
19287                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19288                }
19289                if (tr.getRootActivity() != null) {
19290                    moveTaskToFrontLocked(tr.taskId, 0, null);
19291                    return;
19292                }
19293            }
19294
19295            startActivityFromRecentsInner(tr.taskId, null);
19296        }
19297
19298        @Override
19299        public int startActivity(IBinder whoThread, String callingPackage,
19300                Intent intent, String resolvedType, Bundle options) {
19301            checkCaller();
19302
19303            int callingUser = UserHandle.getCallingUserId();
19304            TaskRecord tr;
19305            IApplicationThread appThread;
19306            synchronized (ActivityManagerService.this) {
19307                tr = recentTaskForIdLocked(mTaskId);
19308                if (tr == null) {
19309                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19310                }
19311                appThread = ApplicationThreadNative.asInterface(whoThread);
19312                if (appThread == null) {
19313                    throw new IllegalArgumentException("Bad app thread " + appThread);
19314                }
19315            }
19316            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19317                    resolvedType, null, null, null, null, 0, 0, null, null,
19318                    null, options, callingUser, null, tr);
19319        }
19320
19321        @Override
19322        public void setExcludeFromRecents(boolean exclude) {
19323            checkCaller();
19324
19325            synchronized (ActivityManagerService.this) {
19326                long origId = Binder.clearCallingIdentity();
19327                try {
19328                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19329                    if (tr == null) {
19330                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19331                    }
19332                    Intent intent = tr.getBaseIntent();
19333                    if (exclude) {
19334                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19335                    } else {
19336                        intent.setFlags(intent.getFlags()
19337                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19338                    }
19339                } finally {
19340                    Binder.restoreCallingIdentity(origId);
19341                }
19342            }
19343        }
19344    }
19345}
19346