ActivityManagerService.java revision de313753d0fd0173d0558518d9a410fdc0127c76
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    final static class Association {
753        final int mSourceUid;
754        final String mSourceProcess;
755        final int mTargetUid;
756        final ComponentName mTargetComponent;
757        final String mTargetProcess;
758
759        int mCount;
760        long mTime;
761
762        int mNesting;
763        long mStartTime;
764
765        Association(int sourceUid, String sourceProcess, int targetUid,
766                ComponentName targetComponent, String targetProcess) {
767            mSourceUid = sourceUid;
768            mSourceProcess = sourceProcess;
769            mTargetUid = targetUid;
770            mTargetComponent = targetComponent;
771            mTargetProcess = targetProcess;
772        }
773    }
774
775    /**
776     * When service association tracking is enabled, this is all of the associations we
777     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
778     * -> association data.
779     */
780    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
781            mAssociations = new SparseArray<>();
782    boolean mTrackingAssociations;
783
784    /**
785     * Backup/restore process management
786     */
787    String mBackupAppName = null;
788    BackupRecord mBackupTarget = null;
789
790    final ProviderMap mProviderMap;
791
792    /**
793     * List of content providers who have clients waiting for them.  The
794     * application is currently being launched and the provider will be
795     * removed from this list once it is published.
796     */
797    final ArrayList<ContentProviderRecord> mLaunchingProviders
798            = new ArrayList<ContentProviderRecord>();
799
800    /**
801     * File storing persisted {@link #mGrantedUriPermissions}.
802     */
803    private final AtomicFile mGrantFile;
804
805    /** XML constants used in {@link #mGrantFile} */
806    private static final String TAG_URI_GRANTS = "uri-grants";
807    private static final String TAG_URI_GRANT = "uri-grant";
808    private static final String ATTR_USER_HANDLE = "userHandle";
809    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
810    private static final String ATTR_TARGET_USER_ID = "targetUserId";
811    private static final String ATTR_SOURCE_PKG = "sourcePkg";
812    private static final String ATTR_TARGET_PKG = "targetPkg";
813    private static final String ATTR_URI = "uri";
814    private static final String ATTR_MODE_FLAGS = "modeFlags";
815    private static final String ATTR_CREATED_TIME = "createdTime";
816    private static final String ATTR_PREFIX = "prefix";
817
818    /**
819     * Global set of specific {@link Uri} permissions that have been granted.
820     * This optimized lookup structure maps from {@link UriPermission#targetUid}
821     * to {@link UriPermission#uri} to {@link UriPermission}.
822     */
823    @GuardedBy("this")
824    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
825            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
826
827    public static class GrantUri {
828        public final int sourceUserId;
829        public final Uri uri;
830        public boolean prefix;
831
832        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
833            this.sourceUserId = sourceUserId;
834            this.uri = uri;
835            this.prefix = prefix;
836        }
837
838        @Override
839        public int hashCode() {
840            int hashCode = 1;
841            hashCode = 31 * hashCode + sourceUserId;
842            hashCode = 31 * hashCode + uri.hashCode();
843            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
844            return hashCode;
845        }
846
847        @Override
848        public boolean equals(Object o) {
849            if (o instanceof GrantUri) {
850                GrantUri other = (GrantUri) o;
851                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
852                        && prefix == other.prefix;
853            }
854            return false;
855        }
856
857        @Override
858        public String toString() {
859            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
860            if (prefix) result += " [prefix]";
861            return result;
862        }
863
864        public String toSafeString() {
865            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
866            if (prefix) result += " [prefix]";
867            return result;
868        }
869
870        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
871            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
872                    ContentProvider.getUriWithoutUserId(uri), false);
873        }
874    }
875
876    CoreSettingsObserver mCoreSettingsObserver;
877
878    /**
879     * Thread-local storage used to carry caller permissions over through
880     * indirect content-provider access.
881     */
882    private class Identity {
883        public final IBinder token;
884        public final int pid;
885        public final int uid;
886
887        Identity(IBinder _token, int _pid, int _uid) {
888            token = _token;
889            pid = _pid;
890            uid = _uid;
891        }
892    }
893
894    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
895
896    /**
897     * All information we have collected about the runtime performance of
898     * any user id that can impact battery performance.
899     */
900    final BatteryStatsService mBatteryStatsService;
901
902    /**
903     * Information about component usage
904     */
905    UsageStatsManagerInternal mUsageStatsService;
906
907    /**
908     * Information about and control over application operations
909     */
910    final AppOpsService mAppOpsService;
911
912    /**
913     * Save recent tasks information across reboots.
914     */
915    final TaskPersister mTaskPersister;
916
917    /**
918     * Current configuration information.  HistoryRecord objects are given
919     * a reference to this object to indicate which configuration they are
920     * currently running in, so this object must be kept immutable.
921     */
922    Configuration mConfiguration = new Configuration();
923
924    /**
925     * Current sequencing integer of the configuration, for skipping old
926     * configurations.
927     */
928    int mConfigurationSeq = 0;
929
930    /**
931     * Hardware-reported OpenGLES version.
932     */
933    final int GL_ES_VERSION;
934
935    /**
936     * List of initialization arguments to pass to all processes when binding applications to them.
937     * For example, references to the commonly used services.
938     */
939    HashMap<String, IBinder> mAppBindArgs;
940
941    /**
942     * Temporary to avoid allocations.  Protected by main lock.
943     */
944    final StringBuilder mStringBuilder = new StringBuilder(256);
945
946    /**
947     * Used to control how we initialize the service.
948     */
949    ComponentName mTopComponent;
950    String mTopAction = Intent.ACTION_MAIN;
951    String mTopData;
952    boolean mProcessesReady = false;
953    boolean mSystemReady = false;
954    boolean mBooting = false;
955    boolean mCallFinishBooting = false;
956    boolean mBootAnimationComplete = false;
957    boolean mWaitingUpdate = false;
958    boolean mDidUpdate = false;
959    boolean mOnBattery = false;
960    boolean mLaunchWarningShown = false;
961
962    Context mContext;
963
964    int mFactoryTest;
965
966    boolean mCheckedForSetup;
967
968    /**
969     * The time at which we will allow normal application switches again,
970     * after a call to {@link #stopAppSwitches()}.
971     */
972    long mAppSwitchesAllowedTime;
973
974    /**
975     * This is set to true after the first switch after mAppSwitchesAllowedTime
976     * is set; any switches after that will clear the time.
977     */
978    boolean mDidAppSwitch;
979
980    /**
981     * Last time (in realtime) at which we checked for power usage.
982     */
983    long mLastPowerCheckRealtime;
984
985    /**
986     * Last time (in uptime) at which we checked for power usage.
987     */
988    long mLastPowerCheckUptime;
989
990    /**
991     * Set while we are wanting to sleep, to prevent any
992     * activities from being started/resumed.
993     */
994    private boolean mSleeping = false;
995
996    /**
997     * Set while we are running a voice interaction.  This overrides
998     * sleeping while it is active.
999     */
1000    private boolean mRunningVoice = false;
1001
1002    /**
1003     * State of external calls telling us if the device is awake or asleep.
1004     */
1005    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1006
1007    static final int LOCK_SCREEN_HIDDEN = 0;
1008    static final int LOCK_SCREEN_LEAVING = 1;
1009    static final int LOCK_SCREEN_SHOWN = 2;
1010    /**
1011     * State of external call telling us if the lock screen is shown.
1012     */
1013    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1014
1015    /**
1016     * Set if we are shutting down the system, similar to sleeping.
1017     */
1018    boolean mShuttingDown = false;
1019
1020    /**
1021     * Current sequence id for oom_adj computation traversal.
1022     */
1023    int mAdjSeq = 0;
1024
1025    /**
1026     * Current sequence id for process LRU updating.
1027     */
1028    int mLruSeq = 0;
1029
1030    /**
1031     * Keep track of the non-cached/empty process we last found, to help
1032     * determine how to distribute cached/empty processes next time.
1033     */
1034    int mNumNonCachedProcs = 0;
1035
1036    /**
1037     * Keep track of the number of cached hidden procs, to balance oom adj
1038     * distribution between those and empty procs.
1039     */
1040    int mNumCachedHiddenProcs = 0;
1041
1042    /**
1043     * Keep track of the number of service processes we last found, to
1044     * determine on the next iteration which should be B services.
1045     */
1046    int mNumServiceProcs = 0;
1047    int mNewNumAServiceProcs = 0;
1048    int mNewNumServiceProcs = 0;
1049
1050    /**
1051     * Allow the current computed overall memory level of the system to go down?
1052     * This is set to false when we are killing processes for reasons other than
1053     * memory management, so that the now smaller process list will not be taken as
1054     * an indication that memory is tighter.
1055     */
1056    boolean mAllowLowerMemLevel = false;
1057
1058    /**
1059     * The last computed memory level, for holding when we are in a state that
1060     * processes are going away for other reasons.
1061     */
1062    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1063
1064    /**
1065     * The last total number of process we have, to determine if changes actually look
1066     * like a shrinking number of process due to lower RAM.
1067     */
1068    int mLastNumProcesses;
1069
1070    /**
1071     * The uptime of the last time we performed idle maintenance.
1072     */
1073    long mLastIdleTime = SystemClock.uptimeMillis();
1074
1075    /**
1076     * Total time spent with RAM that has been added in the past since the last idle time.
1077     */
1078    long mLowRamTimeSinceLastIdle = 0;
1079
1080    /**
1081     * If RAM is currently low, when that horrible situation started.
1082     */
1083    long mLowRamStartTime = 0;
1084
1085    /**
1086     * For reporting to battery stats the current top application.
1087     */
1088    private String mCurResumedPackage = null;
1089    private int mCurResumedUid = -1;
1090
1091    /**
1092     * For reporting to battery stats the apps currently running foreground
1093     * service.  The ProcessMap is package/uid tuples; each of these contain
1094     * an array of the currently foreground processes.
1095     */
1096    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1097            = new ProcessMap<ArrayList<ProcessRecord>>();
1098
1099    /**
1100     * This is set if we had to do a delayed dexopt of an app before launching
1101     * it, to increase the ANR timeouts in that case.
1102     */
1103    boolean mDidDexOpt;
1104
1105    /**
1106     * Set if the systemServer made a call to enterSafeMode.
1107     */
1108    boolean mSafeMode;
1109
1110    /**
1111     * If true, we are running under a test environment so will sample PSS from processes
1112     * much more rapidly to try to collect better data when the tests are rapidly
1113     * running through apps.
1114     */
1115    boolean mTestPssMode = false;
1116
1117    String mDebugApp = null;
1118    boolean mWaitForDebugger = false;
1119    boolean mDebugTransient = false;
1120    String mOrigDebugApp = null;
1121    boolean mOrigWaitForDebugger = false;
1122    boolean mAlwaysFinishActivities = false;
1123    IActivityController mController = null;
1124    String mProfileApp = null;
1125    ProcessRecord mProfileProc = null;
1126    String mProfileFile;
1127    ParcelFileDescriptor mProfileFd;
1128    int mSamplingInterval = 0;
1129    boolean mAutoStopProfiler = false;
1130    int mProfileType = 0;
1131    String mOpenGlTraceApp = null;
1132
1133    final long[] mTmpLong = new long[1];
1134
1135    static class ProcessChangeItem {
1136        static final int CHANGE_ACTIVITIES = 1<<0;
1137        static final int CHANGE_PROCESS_STATE = 1<<1;
1138        int changes;
1139        int uid;
1140        int pid;
1141        int processState;
1142        boolean foregroundActivities;
1143    }
1144
1145    final RemoteCallbackList<IProcessObserver> mProcessObservers
1146            = new RemoteCallbackList<IProcessObserver>();
1147    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1148
1149    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1150            = new ArrayList<ProcessChangeItem>();
1151    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1152            = new ArrayList<ProcessChangeItem>();
1153
1154    /**
1155     * Runtime CPU use collection thread.  This object's lock is used to
1156     * perform synchronization with the thread (notifying it to run).
1157     */
1158    final Thread mProcessCpuThread;
1159
1160    /**
1161     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1162     * Must acquire this object's lock when accessing it.
1163     * NOTE: this lock will be held while doing long operations (trawling
1164     * through all processes in /proc), so it should never be acquired by
1165     * any critical paths such as when holding the main activity manager lock.
1166     */
1167    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1168            MONITOR_THREAD_CPU_USAGE);
1169    final AtomicLong mLastCpuTime = new AtomicLong(0);
1170    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1171
1172    long mLastWriteTime = 0;
1173
1174    /**
1175     * Used to retain an update lock when the foreground activity is in
1176     * immersive mode.
1177     */
1178    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1179
1180    /**
1181     * Set to true after the system has finished booting.
1182     */
1183    boolean mBooted = false;
1184
1185    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1186    int mProcessLimitOverride = -1;
1187
1188    WindowManagerService mWindowManager;
1189
1190    final ActivityThread mSystemThread;
1191
1192    // Holds the current foreground user's id
1193    int mCurrentUserId = 0;
1194    // Holds the target user's id during a user switch
1195    int mTargetUserId = UserHandle.USER_NULL;
1196    // If there are multiple profiles for the current user, their ids are here
1197    // Currently only the primary user can have managed profiles
1198    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1199
1200    /**
1201     * Mapping from each known user ID to the profile group ID it is associated with.
1202     */
1203    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1204
1205    private UserManagerService mUserManager;
1206
1207    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1208        final ProcessRecord mApp;
1209        final int mPid;
1210        final IApplicationThread mAppThread;
1211
1212        AppDeathRecipient(ProcessRecord app, int pid,
1213                IApplicationThread thread) {
1214            if (localLOGV) Slog.v(
1215                TAG, "New death recipient " + this
1216                + " for thread " + thread.asBinder());
1217            mApp = app;
1218            mPid = pid;
1219            mAppThread = thread;
1220        }
1221
1222        @Override
1223        public void binderDied() {
1224            if (localLOGV) Slog.v(
1225                TAG, "Death received in " + this
1226                + " for thread " + mAppThread.asBinder());
1227            synchronized(ActivityManagerService.this) {
1228                appDiedLocked(mApp, mPid, mAppThread);
1229            }
1230        }
1231    }
1232
1233    static final int SHOW_ERROR_MSG = 1;
1234    static final int SHOW_NOT_RESPONDING_MSG = 2;
1235    static final int SHOW_FACTORY_ERROR_MSG = 3;
1236    static final int UPDATE_CONFIGURATION_MSG = 4;
1237    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1238    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1239    static final int SERVICE_TIMEOUT_MSG = 12;
1240    static final int UPDATE_TIME_ZONE = 13;
1241    static final int SHOW_UID_ERROR_MSG = 14;
1242    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1243    static final int PROC_START_TIMEOUT_MSG = 20;
1244    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1245    static final int KILL_APPLICATION_MSG = 22;
1246    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1247    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1248    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1249    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1250    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1251    static final int CLEAR_DNS_CACHE_MSG = 28;
1252    static final int UPDATE_HTTP_PROXY_MSG = 29;
1253    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1254    static final int DISPATCH_PROCESSES_CHANGED = 31;
1255    static final int DISPATCH_PROCESS_DIED = 32;
1256    static final int REPORT_MEM_USAGE_MSG = 33;
1257    static final int REPORT_USER_SWITCH_MSG = 34;
1258    static final int CONTINUE_USER_SWITCH_MSG = 35;
1259    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1260    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1261    static final int PERSIST_URI_GRANTS_MSG = 38;
1262    static final int REQUEST_ALL_PSS_MSG = 39;
1263    static final int START_PROFILES_MSG = 40;
1264    static final int UPDATE_TIME = 41;
1265    static final int SYSTEM_USER_START_MSG = 42;
1266    static final int SYSTEM_USER_CURRENT_MSG = 43;
1267    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1268    static final int FINISH_BOOTING_MSG = 45;
1269    static final int START_USER_SWITCH_MSG = 46;
1270    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1271    static final int DISMISS_DIALOG_MSG = 48;
1272    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1273
1274    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1275    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1276    static final int FIRST_COMPAT_MODE_MSG = 300;
1277    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1278
1279    CompatModeDialog mCompatModeDialog;
1280    long mLastMemUsageReportTime = 0;
1281
1282    /**
1283     * Flag whether the current user is a "monkey", i.e. whether
1284     * the UI is driven by a UI automation tool.
1285     */
1286    private boolean mUserIsMonkey;
1287
1288    /** Flag whether the device has a Recents UI */
1289    boolean mHasRecents;
1290
1291    /** The dimensions of the thumbnails in the Recents UI. */
1292    int mThumbnailWidth;
1293    int mThumbnailHeight;
1294
1295    final ServiceThread mHandlerThread;
1296    final MainHandler mHandler;
1297
1298    final class MainHandler extends Handler {
1299        public MainHandler(Looper looper) {
1300            super(looper, null, true);
1301        }
1302
1303        @Override
1304        public void handleMessage(Message msg) {
1305            switch (msg.what) {
1306            case SHOW_ERROR_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1309                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1310                synchronized (ActivityManagerService.this) {
1311                    ProcessRecord proc = (ProcessRecord)data.get("app");
1312                    AppErrorResult res = (AppErrorResult) data.get("result");
1313                    if (proc != null && proc.crashDialog != null) {
1314                        Slog.e(TAG, "App already has crash dialog: " + proc);
1315                        if (res != null) {
1316                            res.set(0);
1317                        }
1318                        return;
1319                    }
1320                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1321                            >= Process.FIRST_APPLICATION_UID
1322                            && proc.pid != MY_PID);
1323                    for (int userId : mCurrentProfileIds) {
1324                        isBackground &= (proc.userId != userId);
1325                    }
1326                    if (isBackground && !showBackground) {
1327                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1328                        if (res != null) {
1329                            res.set(0);
1330                        }
1331                        return;
1332                    }
1333                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1334                        Dialog d = new AppErrorDialog(mContext,
1335                                ActivityManagerService.this, res, proc);
1336                        d.show();
1337                        proc.crashDialog = d;
1338                    } else {
1339                        // The device is asleep, so just pretend that the user
1340                        // saw a crash dialog and hit "force quit".
1341                        if (res != null) {
1342                            res.set(0);
1343                        }
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_NOT_RESPONDING_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1352                    ProcessRecord proc = (ProcessRecord)data.get("app");
1353                    if (proc != null && proc.anrDialog != null) {
1354                        Slog.e(TAG, "App already has anr dialog: " + proc);
1355                        return;
1356                    }
1357
1358                    Intent intent = new Intent("android.intent.action.ANR");
1359                    if (!mProcessesReady) {
1360                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1361                                | Intent.FLAG_RECEIVER_FOREGROUND);
1362                    }
1363                    broadcastIntentLocked(null, null, intent,
1364                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1365                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1366
1367                    if (mShowDialogs) {
1368                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1369                                mContext, proc, (ActivityRecord)data.get("activity"),
1370                                msg.arg1 != 0);
1371                        d.show();
1372                        proc.anrDialog = d;
1373                    } else {
1374                        // Just kill the app if there is no dialog to be shown.
1375                        killAppAtUsersRequest(proc, null);
1376                    }
1377                }
1378
1379                ensureBootCompleted();
1380            } break;
1381            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1382                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1383                synchronized (ActivityManagerService.this) {
1384                    ProcessRecord proc = (ProcessRecord) data.get("app");
1385                    if (proc == null) {
1386                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1387                        break;
1388                    }
1389                    if (proc.crashDialog != null) {
1390                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1391                        return;
1392                    }
1393                    AppErrorResult res = (AppErrorResult) data.get("result");
1394                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1395                        Dialog d = new StrictModeViolationDialog(mContext,
1396                                ActivityManagerService.this, res, proc);
1397                        d.show();
1398                        proc.crashDialog = d;
1399                    } else {
1400                        // The device is asleep, so just pretend that the user
1401                        // saw a crash dialog and hit "force quit".
1402                        res.set(0);
1403                    }
1404                }
1405                ensureBootCompleted();
1406            } break;
1407            case SHOW_FACTORY_ERROR_MSG: {
1408                Dialog d = new FactoryErrorDialog(
1409                    mContext, msg.getData().getCharSequence("msg"));
1410                d.show();
1411                ensureBootCompleted();
1412            } break;
1413            case UPDATE_CONFIGURATION_MSG: {
1414                final ContentResolver resolver = mContext.getContentResolver();
1415                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1416            } break;
1417            case GC_BACKGROUND_PROCESSES_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    performAppGcsIfAppropriateLocked();
1420                }
1421            } break;
1422            case WAIT_FOR_DEBUGGER_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    ProcessRecord app = (ProcessRecord)msg.obj;
1425                    if (msg.arg1 != 0) {
1426                        if (!app.waitedForDebugger) {
1427                            Dialog d = new AppWaitingForDebuggerDialog(
1428                                    ActivityManagerService.this,
1429                                    mContext, app);
1430                            app.waitDialog = d;
1431                            app.waitedForDebugger = true;
1432                            d.show();
1433                        }
1434                    } else {
1435                        if (app.waitDialog != null) {
1436                            app.waitDialog.dismiss();
1437                            app.waitDialog = null;
1438                        }
1439                    }
1440                }
1441            } break;
1442            case SERVICE_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1448                    return;
1449                }
1450                mServices.serviceTimeout((ProcessRecord)msg.obj);
1451            } break;
1452            case UPDATE_TIME_ZONE: {
1453                synchronized (ActivityManagerService.this) {
1454                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1455                        ProcessRecord r = mLruProcesses.get(i);
1456                        if (r.thread != null) {
1457                            try {
1458                                r.thread.updateTimeZone();
1459                            } catch (RemoteException ex) {
1460                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1461                            }
1462                        }
1463                    }
1464                }
1465            } break;
1466            case CLEAR_DNS_CACHE_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1469                        ProcessRecord r = mLruProcesses.get(i);
1470                        if (r.thread != null) {
1471                            try {
1472                                r.thread.clearDnsCache();
1473                            } catch (RemoteException ex) {
1474                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1475                            }
1476                        }
1477                    }
1478                }
1479            } break;
1480            case UPDATE_HTTP_PROXY_MSG: {
1481                ProxyInfo proxy = (ProxyInfo)msg.obj;
1482                String host = "";
1483                String port = "";
1484                String exclList = "";
1485                Uri pacFileUrl = Uri.EMPTY;
1486                if (proxy != null) {
1487                    host = proxy.getHost();
1488                    port = Integer.toString(proxy.getPort());
1489                    exclList = proxy.getExclusionListAsString();
1490                    pacFileUrl = proxy.getPacFileUrl();
1491                }
1492                synchronized (ActivityManagerService.this) {
1493                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1494                        ProcessRecord r = mLruProcesses.get(i);
1495                        if (r.thread != null) {
1496                            try {
1497                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1498                            } catch (RemoteException ex) {
1499                                Slog.w(TAG, "Failed to update http proxy for: " +
1500                                        r.info.processName);
1501                            }
1502                        }
1503                    }
1504                }
1505            } break;
1506            case SHOW_UID_ERROR_MSG: {
1507                if (mShowDialogs) {
1508                    AlertDialog d = new BaseErrorDialog(mContext);
1509                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1510                    d.setCancelable(false);
1511                    d.setTitle(mContext.getText(R.string.android_system_label));
1512                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1513                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1514                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1515                    d.show();
1516                }
1517            } break;
1518            case SHOW_FINGERPRINT_ERROR_MSG: {
1519                if (mShowDialogs) {
1520                    AlertDialog d = new BaseErrorDialog(mContext);
1521                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1522                    d.setCancelable(false);
1523                    d.setTitle(mContext.getText(R.string.android_system_label));
1524                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1525                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1526                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1527                    d.show();
1528                }
1529            } break;
1530            case PROC_START_TIMEOUT_MSG: {
1531                if (mDidDexOpt) {
1532                    mDidDexOpt = false;
1533                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1534                    nmsg.obj = msg.obj;
1535                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1536                    return;
1537                }
1538                ProcessRecord app = (ProcessRecord)msg.obj;
1539                synchronized (ActivityManagerService.this) {
1540                    processStartTimedOutLocked(app);
1541                }
1542            } break;
1543            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1546                }
1547            } break;
1548            case KILL_APPLICATION_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    int appid = msg.arg1;
1551                    boolean restart = (msg.arg2 == 1);
1552                    Bundle bundle = (Bundle)msg.obj;
1553                    String pkg = bundle.getString("pkg");
1554                    String reason = bundle.getString("reason");
1555                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1556                            false, UserHandle.USER_ALL, reason);
1557                }
1558            } break;
1559            case FINALIZE_PENDING_INTENT_MSG: {
1560                ((PendingIntentRecord)msg.obj).completeFinalize();
1561            } break;
1562            case POST_HEAVY_NOTIFICATION_MSG: {
1563                INotificationManager inm = NotificationManager.getService();
1564                if (inm == null) {
1565                    return;
1566                }
1567
1568                ActivityRecord root = (ActivityRecord)msg.obj;
1569                ProcessRecord process = root.app;
1570                if (process == null) {
1571                    return;
1572                }
1573
1574                try {
1575                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1576                    String text = mContext.getString(R.string.heavy_weight_notification,
1577                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1578                    Notification notification = new Notification();
1579                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1580                    notification.when = 0;
1581                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1582                    notification.tickerText = text;
1583                    notification.defaults = 0; // please be quiet
1584                    notification.sound = null;
1585                    notification.vibrate = null;
1586                    notification.color = mContext.getResources().getColor(
1587                            com.android.internal.R.color.system_notification_accent_color);
1588                    notification.setLatestEventInfo(context, text,
1589                            mContext.getText(R.string.heavy_weight_notification_detail),
1590                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1591                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1592                                    new UserHandle(root.userId)));
1593
1594                    try {
1595                        int[] outId = new int[1];
1596                        inm.enqueueNotificationWithTag("android", "android", null,
1597                                R.string.heavy_weight_notification,
1598                                notification, outId, root.userId);
1599                    } catch (RuntimeException e) {
1600                        Slog.w(ActivityManagerService.TAG,
1601                                "Error showing notification for heavy-weight app", e);
1602                    } catch (RemoteException e) {
1603                    }
1604                } catch (NameNotFoundException e) {
1605                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1606                }
1607            } break;
1608            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1609                INotificationManager inm = NotificationManager.getService();
1610                if (inm == null) {
1611                    return;
1612                }
1613                try {
1614                    inm.cancelNotificationWithTag("android", null,
1615                            R.string.heavy_weight_notification,  msg.arg1);
1616                } catch (RuntimeException e) {
1617                    Slog.w(ActivityManagerService.TAG,
1618                            "Error canceling notification for service", e);
1619                } catch (RemoteException e) {
1620                }
1621            } break;
1622            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    checkExcessivePowerUsageLocked(true);
1625                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1626                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1627                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1628                }
1629            } break;
1630            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1631                synchronized (ActivityManagerService.this) {
1632                    ActivityRecord ar = (ActivityRecord)msg.obj;
1633                    if (mCompatModeDialog != null) {
1634                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1635                                ar.info.applicationInfo.packageName)) {
1636                            return;
1637                        }
1638                        mCompatModeDialog.dismiss();
1639                        mCompatModeDialog = null;
1640                    }
1641                    if (ar != null && false) {
1642                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1643                                ar.packageName)) {
1644                            int mode = mCompatModePackages.computeCompatModeLocked(
1645                                    ar.info.applicationInfo);
1646                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1647                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1648                                mCompatModeDialog = new CompatModeDialog(
1649                                        ActivityManagerService.this, mContext,
1650                                        ar.info.applicationInfo);
1651                                mCompatModeDialog.show();
1652                            }
1653                        }
1654                    }
1655                }
1656                break;
1657            }
1658            case DISPATCH_PROCESSES_CHANGED: {
1659                dispatchProcessesChanged();
1660                break;
1661            }
1662            case DISPATCH_PROCESS_DIED: {
1663                final int pid = msg.arg1;
1664                final int uid = msg.arg2;
1665                dispatchProcessDied(pid, uid);
1666                break;
1667            }
1668            case REPORT_MEM_USAGE_MSG: {
1669                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1670                Thread thread = new Thread() {
1671                    @Override public void run() {
1672                        reportMemUsage(memInfos);
1673                    }
1674                };
1675                thread.start();
1676                break;
1677            }
1678            case START_USER_SWITCH_MSG: {
1679                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1680                break;
1681            }
1682            case REPORT_USER_SWITCH_MSG: {
1683                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1684                break;
1685            }
1686            case CONTINUE_USER_SWITCH_MSG: {
1687                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1688                break;
1689            }
1690            case USER_SWITCH_TIMEOUT_MSG: {
1691                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1692                break;
1693            }
1694            case IMMERSIVE_MODE_LOCK_MSG: {
1695                final boolean nextState = (msg.arg1 != 0);
1696                if (mUpdateLock.isHeld() != nextState) {
1697                    if (DEBUG_IMMERSIVE) {
1698                        final ActivityRecord r = (ActivityRecord) msg.obj;
1699                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1700                    }
1701                    if (nextState) {
1702                        mUpdateLock.acquire();
1703                    } else {
1704                        mUpdateLock.release();
1705                    }
1706                }
1707                break;
1708            }
1709            case PERSIST_URI_GRANTS_MSG: {
1710                writeGrantedUriPermissions();
1711                break;
1712            }
1713            case REQUEST_ALL_PSS_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1716                }
1717                break;
1718            }
1719            case START_PROFILES_MSG: {
1720                synchronized (ActivityManagerService.this) {
1721                    startProfilesLocked();
1722                }
1723                break;
1724            }
1725            case UPDATE_TIME: {
1726                synchronized (ActivityManagerService.this) {
1727                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1728                        ProcessRecord r = mLruProcesses.get(i);
1729                        if (r.thread != null) {
1730                            try {
1731                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1732                            } catch (RemoteException ex) {
1733                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1734                            }
1735                        }
1736                    }
1737                }
1738                break;
1739            }
1740            case SYSTEM_USER_START_MSG: {
1741                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1742                        Integer.toString(msg.arg1), msg.arg1);
1743                mSystemServiceManager.startUser(msg.arg1);
1744                break;
1745            }
1746            case SYSTEM_USER_CURRENT_MSG: {
1747                mBatteryStatsService.noteEvent(
1748                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1749                        Integer.toString(msg.arg2), msg.arg2);
1750                mBatteryStatsService.noteEvent(
1751                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1752                        Integer.toString(msg.arg1), msg.arg1);
1753                mSystemServiceManager.switchUser(msg.arg1);
1754                break;
1755            }
1756            case ENTER_ANIMATION_COMPLETE_MSG: {
1757                synchronized (ActivityManagerService.this) {
1758                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1759                    if (r != null && r.app != null && r.app.thread != null) {
1760                        try {
1761                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1762                        } catch (RemoteException e) {
1763                        }
1764                    }
1765                }
1766                break;
1767            }
1768            case FINISH_BOOTING_MSG: {
1769                if (msg.arg1 != 0) {
1770                    finishBooting();
1771                }
1772                if (msg.arg2 != 0) {
1773                    enableScreenAfterBoot();
1774                }
1775                break;
1776            }
1777            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1778                try {
1779                    Locale l = (Locale) msg.obj;
1780                    IBinder service = ServiceManager.getService("mount");
1781                    IMountService mountService = IMountService.Stub.asInterface(service);
1782                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1783                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1784                } catch (RemoteException e) {
1785                    Log.e(TAG, "Error storing locale for decryption UI", e);
1786                }
1787                break;
1788            }
1789            case DISMISS_DIALOG_MSG: {
1790                final Dialog d = (Dialog) msg.obj;
1791                d.dismiss();
1792                break;
1793            }
1794            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1795                synchronized (ActivityManagerService.this) {
1796                    int i = mTaskStackListeners.beginBroadcast();
1797                    while (i > 0) {
1798                        i--;
1799                        try {
1800                            // Make a one-way callback to the listener
1801                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1802                        } catch (RemoteException e){
1803                            // Handled by the RemoteCallbackList
1804                        }
1805                    }
1806                    mTaskStackListeners.finishBroadcast();
1807                }
1808                break;
1809            }
1810            }
1811        }
1812    };
1813
1814    static final int COLLECT_PSS_BG_MSG = 1;
1815
1816    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1817        @Override
1818        public void handleMessage(Message msg) {
1819            switch (msg.what) {
1820            case COLLECT_PSS_BG_MSG: {
1821                long start = SystemClock.uptimeMillis();
1822                MemInfoReader memInfo = null;
1823                synchronized (ActivityManagerService.this) {
1824                    if (mFullPssPending) {
1825                        mFullPssPending = false;
1826                        memInfo = new MemInfoReader();
1827                    }
1828                }
1829                if (memInfo != null) {
1830                    updateCpuStatsNow();
1831                    long nativeTotalPss = 0;
1832                    synchronized (mProcessCpuTracker) {
1833                        final int N = mProcessCpuTracker.countStats();
1834                        for (int j=0; j<N; j++) {
1835                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1836                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (ActivityManagerService.this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1855                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1856                    }
1857                }
1858
1859                int num = 0;
1860                long[] tmp = new long[1];
1861                do {
1862                    ProcessRecord proc;
1863                    int procState;
1864                    int pid;
1865                    long lastPssTime;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (mPendingPssProcesses.size() <= 0) {
1868                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.remove(0);
1874                        procState = proc.pssProcState;
1875                        lastPssTime = proc.lastPssTime;
1876                        if (proc.thread != null && procState == proc.setProcState
1877                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1878                                        < SystemClock.uptimeMillis()) {
1879                            pid = proc.pid;
1880                        } else {
1881                            proc = null;
1882                            pid = 0;
1883                        }
1884                    }
1885                    if (proc != null) {
1886                        long pss = Debug.getPss(pid, tmp, null);
1887                        synchronized (ActivityManagerService.this) {
1888                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1889                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1890                                num++;
1891                                recordPssSample(proc, procState, pss, tmp[0],
1892                                        SystemClock.uptimeMillis());
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    public void setSystemProcess() {
1903        try {
1904            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1905            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1906            ServiceManager.addService("meminfo", new MemBinder(this));
1907            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1908            ServiceManager.addService("dbinfo", new DbBinder(this));
1909            if (MONITOR_CPU_USAGE) {
1910                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1911            }
1912            ServiceManager.addService("permission", new PermissionController(this));
1913
1914            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1915                    "android", STOCK_PM_FLAGS);
1916            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1917
1918            synchronized (this) {
1919                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1920                app.persistent = true;
1921                app.pid = MY_PID;
1922                app.maxAdj = ProcessList.SYSTEM_ADJ;
1923                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1924                mProcessNames.put(app.processName, app.uid, app);
1925                synchronized (mPidsSelfLocked) {
1926                    mPidsSelfLocked.put(app.pid, app);
1927                }
1928                updateLruProcessLocked(app, false, null);
1929                updateOomAdjLocked();
1930            }
1931        } catch (PackageManager.NameNotFoundException e) {
1932            throw new RuntimeException(
1933                    "Unable to find android system package", e);
1934        }
1935    }
1936
1937    public void setWindowManager(WindowManagerService wm) {
1938        mWindowManager = wm;
1939        mStackSupervisor.setWindowManager(wm);
1940    }
1941
1942    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1943        mUsageStatsService = usageStatsManager;
1944    }
1945
1946    public void startObservingNativeCrashes() {
1947        final NativeCrashListener ncl = new NativeCrashListener(this);
1948        ncl.start();
1949    }
1950
1951    public IAppOpsService getAppOpsService() {
1952        return mAppOpsService;
1953    }
1954
1955    static class MemBinder extends Binder {
1956        ActivityManagerService mActivityManagerService;
1957        MemBinder(ActivityManagerService activityManagerService) {
1958            mActivityManagerService = activityManagerService;
1959        }
1960
1961        @Override
1962        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1963            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1964                    != PackageManager.PERMISSION_GRANTED) {
1965                pw.println("Permission Denial: can't dump meminfo from from pid="
1966                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1967                        + " without permission " + android.Manifest.permission.DUMP);
1968                return;
1969            }
1970
1971            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1972        }
1973    }
1974
1975    static class GraphicsBinder extends Binder {
1976        ActivityManagerService mActivityManagerService;
1977        GraphicsBinder(ActivityManagerService activityManagerService) {
1978            mActivityManagerService = activityManagerService;
1979        }
1980
1981        @Override
1982        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1983            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1984                    != PackageManager.PERMISSION_GRANTED) {
1985                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1986                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1987                        + " without permission " + android.Manifest.permission.DUMP);
1988                return;
1989            }
1990
1991            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1992        }
1993    }
1994
1995    static class DbBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        DbBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump dbinfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpDbInfo(fd, pw, args);
2012        }
2013    }
2014
2015    static class CpuBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        CpuBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            synchronized (mActivityManagerService.mProcessCpuTracker) {
2032                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2033                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2034                        SystemClock.uptimeMillis()));
2035            }
2036        }
2037    }
2038
2039    public static final class Lifecycle extends SystemService {
2040        private final ActivityManagerService mService;
2041
2042        public Lifecycle(Context context) {
2043            super(context);
2044            mService = new ActivityManagerService(context);
2045        }
2046
2047        @Override
2048        public void onStart() {
2049            mService.start();
2050        }
2051
2052        public ActivityManagerService getService() {
2053            return mService;
2054        }
2055    }
2056
2057    // Note: This method is invoked on the main thread but may need to attach various
2058    // handlers to other threads.  So take care to be explicit about the looper.
2059    public ActivityManagerService(Context systemContext) {
2060        mContext = systemContext;
2061        mFactoryTest = FactoryTest.getMode();
2062        mSystemThread = ActivityThread.currentActivityThread();
2063
2064        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2065
2066        mHandlerThread = new ServiceThread(TAG,
2067                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2068        mHandlerThread.start();
2069        mHandler = new MainHandler(mHandlerThread.getLooper());
2070
2071        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2072                "foreground", BROADCAST_FG_TIMEOUT, false);
2073        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2074                "background", BROADCAST_BG_TIMEOUT, true);
2075        mBroadcastQueues[0] = mFgBroadcastQueue;
2076        mBroadcastQueues[1] = mBgBroadcastQueue;
2077
2078        mServices = new ActiveServices(this);
2079        mProviderMap = new ProviderMap(this);
2080
2081        // TODO: Move creation of battery stats service outside of activity manager service.
2082        File dataDir = Environment.getDataDirectory();
2083        File systemDir = new File(dataDir, "system");
2084        systemDir.mkdirs();
2085        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2086        mBatteryStatsService.getActiveStatistics().readLocked();
2087        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2088        mOnBattery = DEBUG_POWER ? true
2089                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2090        mBatteryStatsService.getActiveStatistics().setCallback(this);
2091
2092        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2093
2094        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2095
2096        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2097
2098        // User 0 is the first and only user that runs at boot.
2099        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2100        mUserLru.add(Integer.valueOf(0));
2101        updateStartedUserArrayLocked();
2102
2103        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2104            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2105
2106        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2107
2108        mConfiguration.setToDefaults();
2109        mConfiguration.locale = Locale.getDefault();
2110
2111        mConfigurationSeq = mConfiguration.seq = 1;
2112        mProcessCpuTracker.init();
2113
2114        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2115        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2116        mStackSupervisor = new ActivityStackSupervisor(this);
2117        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2118
2119        mProcessCpuThread = new Thread("CpuTracker") {
2120            @Override
2121            public void run() {
2122                while (true) {
2123                    try {
2124                        try {
2125                            synchronized(this) {
2126                                final long now = SystemClock.uptimeMillis();
2127                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2128                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2129                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2130                                //        + ", write delay=" + nextWriteDelay);
2131                                if (nextWriteDelay < nextCpuDelay) {
2132                                    nextCpuDelay = nextWriteDelay;
2133                                }
2134                                if (nextCpuDelay > 0) {
2135                                    mProcessCpuMutexFree.set(true);
2136                                    this.wait(nextCpuDelay);
2137                                }
2138                            }
2139                        } catch (InterruptedException e) {
2140                        }
2141                        updateCpuStatsNow();
2142                    } catch (Exception e) {
2143                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2144                    }
2145                }
2146            }
2147        };
2148
2149        Watchdog.getInstance().addMonitor(this);
2150        Watchdog.getInstance().addThread(mHandler);
2151    }
2152
2153    public void setSystemServiceManager(SystemServiceManager mgr) {
2154        mSystemServiceManager = mgr;
2155    }
2156
2157    public void setInstaller(Installer installer) {
2158        mInstaller = installer;
2159    }
2160
2161    private void start() {
2162        Process.removeAllProcessGroups();
2163        mProcessCpuThread.start();
2164
2165        mBatteryStatsService.publish(mContext);
2166        mAppOpsService.publish(mContext);
2167        Slog.d("AppOps", "AppOpsService published");
2168        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2169    }
2170
2171    public void initPowerManagement() {
2172        mStackSupervisor.initPowerManagement();
2173        mBatteryStatsService.initPowerManagement();
2174    }
2175
2176    @Override
2177    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2178            throws RemoteException {
2179        if (code == SYSPROPS_TRANSACTION) {
2180            // We need to tell all apps about the system property change.
2181            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2182            synchronized(this) {
2183                final int NP = mProcessNames.getMap().size();
2184                for (int ip=0; ip<NP; ip++) {
2185                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2186                    final int NA = apps.size();
2187                    for (int ia=0; ia<NA; ia++) {
2188                        ProcessRecord app = apps.valueAt(ia);
2189                        if (app.thread != null) {
2190                            procs.add(app.thread.asBinder());
2191                        }
2192                    }
2193                }
2194            }
2195
2196            int N = procs.size();
2197            for (int i=0; i<N; i++) {
2198                Parcel data2 = Parcel.obtain();
2199                try {
2200                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2201                } catch (RemoteException e) {
2202                }
2203                data2.recycle();
2204            }
2205        }
2206        try {
2207            return super.onTransact(code, data, reply, flags);
2208        } catch (RuntimeException e) {
2209            // The activity manager only throws security exceptions, so let's
2210            // log all others.
2211            if (!(e instanceof SecurityException)) {
2212                Slog.wtf(TAG, "Activity Manager Crash", e);
2213            }
2214            throw e;
2215        }
2216    }
2217
2218    void updateCpuStats() {
2219        final long now = SystemClock.uptimeMillis();
2220        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2221            return;
2222        }
2223        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2224            synchronized (mProcessCpuThread) {
2225                mProcessCpuThread.notify();
2226            }
2227        }
2228    }
2229
2230    void updateCpuStatsNow() {
2231        synchronized (mProcessCpuTracker) {
2232            mProcessCpuMutexFree.set(false);
2233            final long now = SystemClock.uptimeMillis();
2234            boolean haveNewCpuStats = false;
2235
2236            if (MONITOR_CPU_USAGE &&
2237                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2238                mLastCpuTime.set(now);
2239                haveNewCpuStats = true;
2240                mProcessCpuTracker.update();
2241                //Slog.i(TAG, mProcessCpu.printCurrentState());
2242                //Slog.i(TAG, "Total CPU usage: "
2243                //        + mProcessCpu.getTotalCpuPercent() + "%");
2244
2245                // Slog the cpu usage if the property is set.
2246                if ("true".equals(SystemProperties.get("events.cpu"))) {
2247                    int user = mProcessCpuTracker.getLastUserTime();
2248                    int system = mProcessCpuTracker.getLastSystemTime();
2249                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2250                    int irq = mProcessCpuTracker.getLastIrqTime();
2251                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2252                    int idle = mProcessCpuTracker.getLastIdleTime();
2253
2254                    int total = user + system + iowait + irq + softIrq + idle;
2255                    if (total == 0) total = 1;
2256
2257                    EventLog.writeEvent(EventLogTags.CPU,
2258                            ((user+system+iowait+irq+softIrq) * 100) / total,
2259                            (user * 100) / total,
2260                            (system * 100) / total,
2261                            (iowait * 100) / total,
2262                            (irq * 100) / total,
2263                            (softIrq * 100) / total);
2264                }
2265            }
2266
2267            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2268            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2269            synchronized(bstats) {
2270                synchronized(mPidsSelfLocked) {
2271                    if (haveNewCpuStats) {
2272                        if (mOnBattery) {
2273                            int perc = bstats.startAddingCpuLocked();
2274                            int totalUTime = 0;
2275                            int totalSTime = 0;
2276                            final int N = mProcessCpuTracker.countStats();
2277                            for (int i=0; i<N; i++) {
2278                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2279                                if (!st.working) {
2280                                    continue;
2281                                }
2282                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2283                                int otherUTime = (st.rel_utime*perc)/100;
2284                                int otherSTime = (st.rel_stime*perc)/100;
2285                                totalUTime += otherUTime;
2286                                totalSTime += otherSTime;
2287                                if (pr != null) {
2288                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2289                                    if (ps == null || !ps.isActive()) {
2290                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2291                                                pr.info.uid, pr.processName);
2292                                    }
2293                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2294                                            st.rel_stime-otherSTime);
2295                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2296                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2297                                } else {
2298                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2299                                    if (ps == null || !ps.isActive()) {
2300                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2301                                                bstats.mapUid(st.uid), st.name);
2302                                    }
2303                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2304                                            st.rel_stime-otherSTime);
2305                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2306                                }
2307                            }
2308                            bstats.finishAddingCpuLocked(perc, totalUTime,
2309                                    totalSTime, cpuSpeedTimes);
2310                        }
2311                    }
2312                }
2313
2314                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2315                    mLastWriteTime = now;
2316                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2317                }
2318            }
2319        }
2320    }
2321
2322    @Override
2323    public void batteryNeedsCpuUpdate() {
2324        updateCpuStatsNow();
2325    }
2326
2327    @Override
2328    public void batteryPowerChanged(boolean onBattery) {
2329        // When plugging in, update the CPU stats first before changing
2330        // the plug state.
2331        updateCpuStatsNow();
2332        synchronized (this) {
2333            synchronized(mPidsSelfLocked) {
2334                mOnBattery = DEBUG_POWER ? true : onBattery;
2335            }
2336        }
2337    }
2338
2339    /**
2340     * Initialize the application bind args. These are passed to each
2341     * process when the bindApplication() IPC is sent to the process. They're
2342     * lazily setup to make sure the services are running when they're asked for.
2343     */
2344    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2345        if (mAppBindArgs == null) {
2346            mAppBindArgs = new HashMap<>();
2347
2348            // Isolated processes won't get this optimization, so that we don't
2349            // violate the rules about which services they have access to.
2350            if (!isolated) {
2351                // Setup the application init args
2352                mAppBindArgs.put("package", ServiceManager.getService("package"));
2353                mAppBindArgs.put("window", ServiceManager.getService("window"));
2354                mAppBindArgs.put(Context.ALARM_SERVICE,
2355                        ServiceManager.getService(Context.ALARM_SERVICE));
2356            }
2357        }
2358        return mAppBindArgs;
2359    }
2360
2361    final void setFocusedActivityLocked(ActivityRecord r) {
2362        if (mFocusedActivity != r) {
2363            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2364            mFocusedActivity = r;
2365            if (r.task != null && r.task.voiceInteractor != null) {
2366                startRunningVoiceLocked();
2367            } else {
2368                finishRunningVoiceLocked();
2369            }
2370            mStackSupervisor.setFocusedStack(r);
2371            if (r != null) {
2372                mWindowManager.setFocusedApp(r.appToken, true);
2373            }
2374            applyUpdateLockStateLocked(r);
2375        }
2376        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2377                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2378    }
2379
2380    final void clearFocusedActivity(ActivityRecord r) {
2381        if (mFocusedActivity == r) {
2382            mFocusedActivity = null;
2383        }
2384    }
2385
2386    @Override
2387    public void setFocusedStack(int stackId) {
2388        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2389        synchronized (ActivityManagerService.this) {
2390            ActivityStack stack = mStackSupervisor.getStack(stackId);
2391            if (stack != null) {
2392                ActivityRecord r = stack.topRunningActivityLocked(null);
2393                if (r != null) {
2394                    setFocusedActivityLocked(r);
2395                }
2396            }
2397        }
2398    }
2399
2400    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2401    @Override
2402    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2403        synchronized (ActivityManagerService.this) {
2404            if (listener != null) {
2405                mTaskStackListeners.register(listener);
2406            }
2407        }
2408    }
2409
2410    @Override
2411    public void notifyActivityDrawn(IBinder token) {
2412        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2413        synchronized (this) {
2414            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2415            if (r != null) {
2416                r.task.stack.notifyActivityDrawnLocked(r);
2417            }
2418        }
2419    }
2420
2421    final void applyUpdateLockStateLocked(ActivityRecord r) {
2422        // Modifications to the UpdateLock state are done on our handler, outside
2423        // the activity manager's locks.  The new state is determined based on the
2424        // state *now* of the relevant activity record.  The object is passed to
2425        // the handler solely for logging detail, not to be consulted/modified.
2426        final boolean nextState = r != null && r.immersive;
2427        mHandler.sendMessage(
2428                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2429    }
2430
2431    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2432        Message msg = Message.obtain();
2433        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2434        msg.obj = r.task.askedCompatMode ? null : r;
2435        mHandler.sendMessage(msg);
2436    }
2437
2438    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2439            String what, Object obj, ProcessRecord srcApp) {
2440        app.lastActivityTime = now;
2441
2442        if (app.activities.size() > 0) {
2443            // Don't want to touch dependent processes that are hosting activities.
2444            return index;
2445        }
2446
2447        int lrui = mLruProcesses.lastIndexOf(app);
2448        if (lrui < 0) {
2449            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2450                    + what + " " + obj + " from " + srcApp);
2451            return index;
2452        }
2453
2454        if (lrui >= index) {
2455            // Don't want to cause this to move dependent processes *back* in the
2456            // list as if they were less frequently used.
2457            return index;
2458        }
2459
2460        if (lrui >= mLruProcessActivityStart) {
2461            // Don't want to touch dependent processes that are hosting activities.
2462            return index;
2463        }
2464
2465        mLruProcesses.remove(lrui);
2466        if (index > 0) {
2467            index--;
2468        }
2469        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2470                + " in LRU list: " + app);
2471        mLruProcesses.add(index, app);
2472        return index;
2473    }
2474
2475    final void removeLruProcessLocked(ProcessRecord app) {
2476        int lrui = mLruProcesses.lastIndexOf(app);
2477        if (lrui >= 0) {
2478            if (!app.killed) {
2479                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2480                Process.killProcessQuiet(app.pid);
2481                Process.killProcessGroup(app.info.uid, app.pid);
2482            }
2483            if (lrui <= mLruProcessActivityStart) {
2484                mLruProcessActivityStart--;
2485            }
2486            if (lrui <= mLruProcessServiceStart) {
2487                mLruProcessServiceStart--;
2488            }
2489            mLruProcesses.remove(lrui);
2490        }
2491    }
2492
2493    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2494            ProcessRecord client) {
2495        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2496                || app.treatLikeActivity;
2497        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2498        if (!activityChange && hasActivity) {
2499            // The process has activities, so we are only allowing activity-based adjustments
2500            // to move it.  It should be kept in the front of the list with other
2501            // processes that have activities, and we don't want those to change their
2502            // order except due to activity operations.
2503            return;
2504        }
2505
2506        mLruSeq++;
2507        final long now = SystemClock.uptimeMillis();
2508        app.lastActivityTime = now;
2509
2510        // First a quick reject: if the app is already at the position we will
2511        // put it, then there is nothing to do.
2512        if (hasActivity) {
2513            final int N = mLruProcesses.size();
2514            if (N > 0 && mLruProcesses.get(N-1) == app) {
2515                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2516                return;
2517            }
2518        } else {
2519            if (mLruProcessServiceStart > 0
2520                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2521                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2522                return;
2523            }
2524        }
2525
2526        int lrui = mLruProcesses.lastIndexOf(app);
2527
2528        if (app.persistent && lrui >= 0) {
2529            // We don't care about the position of persistent processes, as long as
2530            // they are in the list.
2531            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2532            return;
2533        }
2534
2535        /* In progress: compute new position first, so we can avoid doing work
2536           if the process is not actually going to move.  Not yet working.
2537        int addIndex;
2538        int nextIndex;
2539        boolean inActivity = false, inService = false;
2540        if (hasActivity) {
2541            // Process has activities, put it at the very tipsy-top.
2542            addIndex = mLruProcesses.size();
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545        } else if (hasService) {
2546            // Process has services, put it at the top of the service list.
2547            addIndex = mLruProcessActivityStart;
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550            inService = true;
2551        } else  {
2552            // Process not otherwise of interest, it goes to the top of the non-service area.
2553            addIndex = mLruProcessServiceStart;
2554            if (client != null) {
2555                int clientIndex = mLruProcesses.lastIndexOf(client);
2556                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2557                        + app);
2558                if (clientIndex >= 0 && addIndex > clientIndex) {
2559                    addIndex = clientIndex;
2560                }
2561            }
2562            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2563        }
2564
2565        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2566                + mLruProcessActivityStart + "): " + app);
2567        */
2568
2569        if (lrui >= 0) {
2570            if (lrui < mLruProcessActivityStart) {
2571                mLruProcessActivityStart--;
2572            }
2573            if (lrui < mLruProcessServiceStart) {
2574                mLruProcessServiceStart--;
2575            }
2576            /*
2577            if (addIndex > lrui) {
2578                addIndex--;
2579            }
2580            if (nextIndex > lrui) {
2581                nextIndex--;
2582            }
2583            */
2584            mLruProcesses.remove(lrui);
2585        }
2586
2587        /*
2588        mLruProcesses.add(addIndex, app);
2589        if (inActivity) {
2590            mLruProcessActivityStart++;
2591        }
2592        if (inService) {
2593            mLruProcessActivityStart++;
2594        }
2595        */
2596
2597        int nextIndex;
2598        if (hasActivity) {
2599            final int N = mLruProcesses.size();
2600            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2601                // Process doesn't have activities, but has clients with
2602                // activities...  move it up, but one below the top (the top
2603                // should always have a real activity).
2604                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2605                mLruProcesses.add(N-1, app);
2606                // To keep it from spamming the LRU list (by making a bunch of clients),
2607                // we will push down any other entries owned by the app.
2608                final int uid = app.info.uid;
2609                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2610                    ProcessRecord subProc = mLruProcesses.get(i);
2611                    if (subProc.info.uid == uid) {
2612                        // We want to push this one down the list.  If the process after
2613                        // it is for the same uid, however, don't do so, because we don't
2614                        // want them internally to be re-ordered.
2615                        if (mLruProcesses.get(i-1).info.uid != uid) {
2616                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2617                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2618                            ProcessRecord tmp = mLruProcesses.get(i);
2619                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2620                            mLruProcesses.set(i-1, tmp);
2621                            i--;
2622                        }
2623                    } else {
2624                        // A gap, we can stop here.
2625                        break;
2626                    }
2627                }
2628            } else {
2629                // Process has activities, put it at the very tipsy-top.
2630                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2631                mLruProcesses.add(app);
2632            }
2633            nextIndex = mLruProcessServiceStart;
2634        } else if (hasService) {
2635            // Process has services, put it at the top of the service list.
2636            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2637            mLruProcesses.add(mLruProcessActivityStart, app);
2638            nextIndex = mLruProcessServiceStart;
2639            mLruProcessActivityStart++;
2640        } else  {
2641            // Process not otherwise of interest, it goes to the top of the non-service area.
2642            int index = mLruProcessServiceStart;
2643            if (client != null) {
2644                // If there is a client, don't allow the process to be moved up higher
2645                // in the list than that client.
2646                int clientIndex = mLruProcesses.lastIndexOf(client);
2647                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2648                        + " when updating " + app);
2649                if (clientIndex <= lrui) {
2650                    // Don't allow the client index restriction to push it down farther in the
2651                    // list than it already is.
2652                    clientIndex = lrui;
2653                }
2654                if (clientIndex >= 0 && index > clientIndex) {
2655                    index = clientIndex;
2656                }
2657            }
2658            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2659            mLruProcesses.add(index, app);
2660            nextIndex = index-1;
2661            mLruProcessActivityStart++;
2662            mLruProcessServiceStart++;
2663        }
2664
2665        // If the app is currently using a content provider or service,
2666        // bump those processes as well.
2667        for (int j=app.connections.size()-1; j>=0; j--) {
2668            ConnectionRecord cr = app.connections.valueAt(j);
2669            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2670                    && cr.binding.service.app != null
2671                    && cr.binding.service.app.lruSeq != mLruSeq
2672                    && !cr.binding.service.app.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2674                        "service connection", cr, app);
2675            }
2676        }
2677        for (int j=app.conProviders.size()-1; j>=0; j--) {
2678            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2679            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2680                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2681                        "provider reference", cpr, app);
2682            }
2683        }
2684    }
2685
2686    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2687        if (uid == Process.SYSTEM_UID) {
2688            // The system gets to run in any process.  If there are multiple
2689            // processes with the same uid, just pick the first (this
2690            // should never happen).
2691            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2692            if (procs == null) return null;
2693            final int N = procs.size();
2694            for (int i = 0; i < N; i++) {
2695                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2696            }
2697        }
2698        ProcessRecord proc = mProcessNames.get(processName, uid);
2699        if (false && proc != null && !keepIfLarge
2700                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2701                && proc.lastCachedPss >= 4000) {
2702            // Turn this condition on to cause killing to happen regularly, for testing.
2703            if (proc.baseProcessTracker != null) {
2704                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2705            }
2706            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2707        } else if (proc != null && !keepIfLarge
2708                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2710            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2711            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2712                if (proc.baseProcessTracker != null) {
2713                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714                }
2715                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2716            }
2717        }
2718        return proc;
2719    }
2720
2721    void ensurePackageDexOpt(String packageName) {
2722        IPackageManager pm = AppGlobals.getPackageManager();
2723        try {
2724            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2725                mDidDexOpt = true;
2726            }
2727        } catch (RemoteException e) {
2728        }
2729    }
2730
2731    boolean isNextTransitionForward() {
2732        int transit = mWindowManager.getPendingAppTransition();
2733        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2734                || transit == AppTransition.TRANSIT_TASK_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2736    }
2737
2738    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2739            String processName, String abiOverride, int uid, Runnable crashHandler) {
2740        synchronized(this) {
2741            ApplicationInfo info = new ApplicationInfo();
2742            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2743            // For isolated processes, the former contains the parent's uid and the latter the
2744            // actual uid of the isolated process.
2745            // In the special case introduced by this method (which is, starting an isolated
2746            // process directly from the SystemServer without an actual parent app process) the
2747            // closest thing to a parent's uid is SYSTEM_UID.
2748            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2749            // the |isolated| logic in the ProcessRecord constructor.
2750            info.uid = Process.SYSTEM_UID;
2751            info.processName = processName;
2752            info.className = entryPoint;
2753            info.packageName = "android";
2754            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2755                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2756                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2757                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2758                    crashHandler);
2759            return proc != null ? proc.pid : 0;
2760        }
2761    }
2762
2763    final ProcessRecord startProcessLocked(String processName,
2764            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2765            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2766            boolean isolated, boolean keepIfLarge) {
2767        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2768                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2769                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2770                null /* crashHandler */);
2771    }
2772
2773    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2774            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2775            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2776            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2777        long startTime = SystemClock.elapsedRealtime();
2778        ProcessRecord app;
2779        if (!isolated) {
2780            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2781            checkTime(startTime, "startProcess: after getProcessRecord");
2782        } else {
2783            // If this is an isolated process, it can't re-use an existing process.
2784            app = null;
2785        }
2786        // We don't have to do anything more if:
2787        // (1) There is an existing application record; and
2788        // (2) The caller doesn't think it is dead, OR there is no thread
2789        //     object attached to it so we know it couldn't have crashed; and
2790        // (3) There is a pid assigned to it, so it is either starting or
2791        //     already running.
2792        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2793                + " app=" + app + " knownToBeDead=" + knownToBeDead
2794                + " thread=" + (app != null ? app.thread : null)
2795                + " pid=" + (app != null ? app.pid : -1));
2796        if (app != null && app.pid > 0) {
2797            if (!knownToBeDead || app.thread == null) {
2798                // We already have the app running, or are waiting for it to
2799                // come up (we have a pid but not yet its thread), so keep it.
2800                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2801                // If this is a new package in the process, add the package to the list
2802                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2803                checkTime(startTime, "startProcess: done, added package to proc");
2804                return app;
2805            }
2806
2807            // An application record is attached to a previous process,
2808            // clean it up now.
2809            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2810            checkTime(startTime, "startProcess: bad proc running, killing");
2811            Process.killProcessGroup(app.info.uid, app.pid);
2812            handleAppDiedLocked(app, true, true);
2813            checkTime(startTime, "startProcess: done killing old proc");
2814        }
2815
2816        String hostingNameStr = hostingName != null
2817                ? hostingName.flattenToShortString() : null;
2818
2819        if (!isolated) {
2820            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2821                // If we are in the background, then check to see if this process
2822                // is bad.  If so, we will just silently fail.
2823                if (mBadProcesses.get(info.processName, info.uid) != null) {
2824                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2825                            + "/" + info.processName);
2826                    return null;
2827                }
2828            } else {
2829                // When the user is explicitly starting a process, then clear its
2830                // crash count so that we won't make it bad until they see at
2831                // least one crash dialog again, and make the process good again
2832                // if it had been bad.
2833                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2834                        + "/" + info.processName);
2835                mProcessCrashTimes.remove(info.processName, info.uid);
2836                if (mBadProcesses.get(info.processName, info.uid) != null) {
2837                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2838                            UserHandle.getUserId(info.uid), info.uid,
2839                            info.processName);
2840                    mBadProcesses.remove(info.processName, info.uid);
2841                    if (app != null) {
2842                        app.bad = false;
2843                    }
2844                }
2845            }
2846        }
2847
2848        if (app == null) {
2849            checkTime(startTime, "startProcess: creating new process record");
2850            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2851            if (app == null) {
2852                Slog.w(TAG, "Failed making new process record for "
2853                        + processName + "/" + info.uid + " isolated=" + isolated);
2854                return null;
2855            }
2856            app.crashHandler = crashHandler;
2857            mProcessNames.put(processName, app.uid, app);
2858            if (isolated) {
2859                mIsolatedProcesses.put(app.uid, app);
2860            }
2861            checkTime(startTime, "startProcess: done creating new process record");
2862        } else {
2863            // If this is a new package in the process, add the package to the list
2864            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2865            checkTime(startTime, "startProcess: added package to existing proc");
2866        }
2867
2868        // If the system is not ready yet, then hold off on starting this
2869        // process until it is.
2870        if (!mProcessesReady
2871                && !isAllowedWhileBooting(info)
2872                && !allowWhileBooting) {
2873            if (!mProcessesOnHold.contains(app)) {
2874                mProcessesOnHold.add(app);
2875            }
2876            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2877            checkTime(startTime, "startProcess: returning with proc on hold");
2878            return app;
2879        }
2880
2881        checkTime(startTime, "startProcess: stepping in to startProcess");
2882        startProcessLocked(
2883                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2884        checkTime(startTime, "startProcess: done starting proc!");
2885        return (app.pid != 0) ? app : null;
2886    }
2887
2888    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2889        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2890    }
2891
2892    private final void startProcessLocked(ProcessRecord app,
2893            String hostingType, String hostingNameStr) {
2894        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2895                null /* entryPoint */, null /* entryPointArgs */);
2896    }
2897
2898    private final void startProcessLocked(ProcessRecord app, String hostingType,
2899            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2900        long startTime = SystemClock.elapsedRealtime();
2901        if (app.pid > 0 && app.pid != MY_PID) {
2902            checkTime(startTime, "startProcess: removing from pids map");
2903            synchronized (mPidsSelfLocked) {
2904                mPidsSelfLocked.remove(app.pid);
2905                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2906            }
2907            checkTime(startTime, "startProcess: done removing from pids map");
2908            app.setPid(0);
2909        }
2910
2911        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2912                "startProcessLocked removing on hold: " + app);
2913        mProcessesOnHold.remove(app);
2914
2915        checkTime(startTime, "startProcess: starting to update cpu stats");
2916        updateCpuStats();
2917        checkTime(startTime, "startProcess: done updating cpu stats");
2918
2919        try {
2920            int uid = app.uid;
2921
2922            int[] gids = null;
2923            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2924            if (!app.isolated) {
2925                int[] permGids = null;
2926                try {
2927                    checkTime(startTime, "startProcess: getting gids from package manager");
2928                    final PackageManager pm = mContext.getPackageManager();
2929                    permGids = pm.getPackageGids(app.info.packageName);
2930
2931                    if (Environment.isExternalStorageEmulated()) {
2932                        checkTime(startTime, "startProcess: checking external storage perm");
2933                        if (pm.checkPermission(
2934                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2935                                app.info.packageName) == PERMISSION_GRANTED) {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2937                        } else {
2938                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2939                        }
2940                    }
2941                } catch (PackageManager.NameNotFoundException e) {
2942                    Slog.w(TAG, "Unable to retrieve gids", e);
2943                }
2944
2945                /*
2946                 * Add shared application and profile GIDs so applications can share some
2947                 * resources like shared libraries and access user-wide resources
2948                 */
2949                if (permGids == null) {
2950                    gids = new int[2];
2951                } else {
2952                    gids = new int[permGids.length + 2];
2953                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2954                }
2955                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2956                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2957            }
2958            checkTime(startTime, "startProcess: building args");
2959            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2960                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2961                        && mTopComponent != null
2962                        && app.processName.equals(mTopComponent.getPackageName())) {
2963                    uid = 0;
2964                }
2965                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2966                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2967                    uid = 0;
2968                }
2969            }
2970            int debugFlags = 0;
2971            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2972                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2973                // Also turn on CheckJNI for debuggable apps. It's quite
2974                // awkward to turn on otherwise.
2975                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2976            }
2977            // Run the app in safe mode if its manifest requests so or the
2978            // system is booted in safe mode.
2979            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2980                mSafeMode == true) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2982            }
2983            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2988            }
2989            if ("1".equals(SystemProperties.get("debug.assert"))) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2991            }
2992
2993            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2994            if (requiredAbi == null) {
2995                requiredAbi = Build.SUPPORTED_ABIS[0];
2996            }
2997
2998            String instructionSet = null;
2999            if (app.info.primaryCpuAbi != null) {
3000                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3001            }
3002
3003            app.gids = gids;
3004            app.requiredAbi = requiredAbi;
3005            app.instructionSet = instructionSet;
3006
3007            // Start the process.  It will either succeed and return a result containing
3008            // the PID of the new process, or else throw a RuntimeException.
3009            boolean isActivityProcess = (entryPoint == null);
3010            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3011            checkTime(startTime, "startProcess: asking zygote to start proc");
3012            Process.ProcessStartResult startResult = Process.start(entryPoint,
3013                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3014                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3015                    app.info.dataDir, entryPointArgs);
3016            checkTime(startTime, "startProcess: returned from zygote!");
3017
3018            if (app.isolated) {
3019                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3020            }
3021            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3022            checkTime(startTime, "startProcess: done updating battery stats");
3023
3024            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3025                    UserHandle.getUserId(uid), startResult.pid, uid,
3026                    app.processName, hostingType,
3027                    hostingNameStr != null ? hostingNameStr : "");
3028
3029            if (app.persistent) {
3030                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3031            }
3032
3033            checkTime(startTime, "startProcess: building log message");
3034            StringBuilder buf = mStringBuilder;
3035            buf.setLength(0);
3036            buf.append("Start proc ");
3037            buf.append(startResult.pid);
3038            buf.append(':');
3039            buf.append(app.processName);
3040            buf.append('/');
3041            UserHandle.formatUid(buf, uid);
3042            if (!isActivityProcess) {
3043                buf.append(" [");
3044                buf.append(entryPoint);
3045                buf.append("]");
3046            }
3047            buf.append(" for ");
3048            buf.append(hostingType);
3049            if (hostingNameStr != null) {
3050                buf.append(" ");
3051                buf.append(hostingNameStr);
3052            }
3053            Slog.i(TAG, buf.toString());
3054            app.setPid(startResult.pid);
3055            app.usingWrapper = startResult.usingWrapper;
3056            app.removed = false;
3057            app.killed = false;
3058            app.killedByAm = false;
3059            checkTime(startTime, "startProcess: starting to update pids map");
3060            synchronized (mPidsSelfLocked) {
3061                this.mPidsSelfLocked.put(startResult.pid, app);
3062                if (isActivityProcess) {
3063                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3064                    msg.obj = app;
3065                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3066                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3067                }
3068            }
3069            checkTime(startTime, "startProcess: done updating pids map");
3070        } catch (RuntimeException e) {
3071            // XXX do better error recovery.
3072            app.setPid(0);
3073            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3074            if (app.isolated) {
3075                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3076            }
3077            Slog.e(TAG, "Failure starting process " + app.processName, e);
3078        }
3079    }
3080
3081    void updateUsageStats(ActivityRecord component, boolean resumed) {
3082        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3083        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3084        if (resumed) {
3085            if (mUsageStatsService != null) {
3086                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3087                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3088            }
3089            synchronized (stats) {
3090                stats.noteActivityResumedLocked(component.app.uid);
3091            }
3092        } else {
3093            if (mUsageStatsService != null) {
3094                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3095                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3096            }
3097            synchronized (stats) {
3098                stats.noteActivityPausedLocked(component.app.uid);
3099            }
3100        }
3101    }
3102
3103    Intent getHomeIntent() {
3104        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3105        intent.setComponent(mTopComponent);
3106        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3107            intent.addCategory(Intent.CATEGORY_HOME);
3108        }
3109        return intent;
3110    }
3111
3112    boolean startHomeActivityLocked(int userId) {
3113        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3114                && mTopAction == null) {
3115            // We are running in factory test mode, but unable to find
3116            // the factory test app, so just sit around displaying the
3117            // error message and don't try to start anything.
3118            return false;
3119        }
3120        Intent intent = getHomeIntent();
3121        ActivityInfo aInfo =
3122            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3123        if (aInfo != null) {
3124            intent.setComponent(new ComponentName(
3125                    aInfo.applicationInfo.packageName, aInfo.name));
3126            // Don't do this if the home app is currently being
3127            // instrumented.
3128            aInfo = new ActivityInfo(aInfo);
3129            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3130            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3131                    aInfo.applicationInfo.uid, true);
3132            if (app == null || app.instrumentationClass == null) {
3133                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3134                mStackSupervisor.startHomeActivity(intent, aInfo);
3135            }
3136        }
3137
3138        return true;
3139    }
3140
3141    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3142        ActivityInfo ai = null;
3143        ComponentName comp = intent.getComponent();
3144        try {
3145            if (comp != null) {
3146                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3147            } else {
3148                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3149                        intent,
3150                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3151                            flags, userId);
3152
3153                if (info != null) {
3154                    ai = info.activityInfo;
3155                }
3156            }
3157        } catch (RemoteException e) {
3158            // ignore
3159        }
3160
3161        return ai;
3162    }
3163
3164    /**
3165     * Starts the "new version setup screen" if appropriate.
3166     */
3167    void startSetupActivityLocked() {
3168        // Only do this once per boot.
3169        if (mCheckedForSetup) {
3170            return;
3171        }
3172
3173        // We will show this screen if the current one is a different
3174        // version than the last one shown, and we are not running in
3175        // low-level factory test mode.
3176        final ContentResolver resolver = mContext.getContentResolver();
3177        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3178                Settings.Global.getInt(resolver,
3179                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3180            mCheckedForSetup = true;
3181
3182            // See if we should be showing the platform update setup UI.
3183            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3184            List<ResolveInfo> ris = mContext.getPackageManager()
3185                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3186
3187            // We don't allow third party apps to replace this.
3188            ResolveInfo ri = null;
3189            for (int i=0; ris != null && i<ris.size(); i++) {
3190                if ((ris.get(i).activityInfo.applicationInfo.flags
3191                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3192                    ri = ris.get(i);
3193                    break;
3194                }
3195            }
3196
3197            if (ri != null) {
3198                String vers = ri.activityInfo.metaData != null
3199                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3200                        : null;
3201                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3202                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3203                            Intent.METADATA_SETUP_VERSION);
3204                }
3205                String lastVers = Settings.Secure.getString(
3206                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3207                if (vers != null && !vers.equals(lastVers)) {
3208                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3209                    intent.setComponent(new ComponentName(
3210                            ri.activityInfo.packageName, ri.activityInfo.name));
3211                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3212                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3213                            null);
3214                }
3215            }
3216        }
3217    }
3218
3219    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3220        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3221    }
3222
3223    void enforceNotIsolatedCaller(String caller) {
3224        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3225            throw new SecurityException("Isolated process not allowed to call " + caller);
3226        }
3227    }
3228
3229    void enforceShellRestriction(String restriction, int userHandle) {
3230        if (Binder.getCallingUid() == Process.SHELL_UID) {
3231            if (userHandle < 0
3232                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3233                throw new SecurityException("Shell does not have permission to access user "
3234                        + userHandle);
3235            }
3236        }
3237    }
3238
3239    @Override
3240    public int getFrontActivityScreenCompatMode() {
3241        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3242        synchronized (this) {
3243            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3244        }
3245    }
3246
3247    @Override
3248    public void setFrontActivityScreenCompatMode(int mode) {
3249        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3250                "setFrontActivityScreenCompatMode");
3251        synchronized (this) {
3252            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3253        }
3254    }
3255
3256    @Override
3257    public int getPackageScreenCompatMode(String packageName) {
3258        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3259        synchronized (this) {
3260            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3261        }
3262    }
3263
3264    @Override
3265    public void setPackageScreenCompatMode(String packageName, int mode) {
3266        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3267                "setPackageScreenCompatMode");
3268        synchronized (this) {
3269            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3270        }
3271    }
3272
3273    @Override
3274    public boolean getPackageAskScreenCompat(String packageName) {
3275        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3276        synchronized (this) {
3277            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3278        }
3279    }
3280
3281    @Override
3282    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3283        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3284                "setPackageAskScreenCompat");
3285        synchronized (this) {
3286            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3287        }
3288    }
3289
3290    private void dispatchProcessesChanged() {
3291        int N;
3292        synchronized (this) {
3293            N = mPendingProcessChanges.size();
3294            if (mActiveProcessChanges.length < N) {
3295                mActiveProcessChanges = new ProcessChangeItem[N];
3296            }
3297            mPendingProcessChanges.toArray(mActiveProcessChanges);
3298            mAvailProcessChanges.addAll(mPendingProcessChanges);
3299            mPendingProcessChanges.clear();
3300            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3301        }
3302
3303        int i = mProcessObservers.beginBroadcast();
3304        while (i > 0) {
3305            i--;
3306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3307            if (observer != null) {
3308                try {
3309                    for (int j=0; j<N; j++) {
3310                        ProcessChangeItem item = mActiveProcessChanges[j];
3311                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3312                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3313                                    + item.pid + " uid=" + item.uid + ": "
3314                                    + item.foregroundActivities);
3315                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3316                                    item.foregroundActivities);
3317                        }
3318                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3319                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3320                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3321                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3322                        }
3323                    }
3324                } catch (RemoteException e) {
3325                }
3326            }
3327        }
3328        mProcessObservers.finishBroadcast();
3329    }
3330
3331    private void dispatchProcessDied(int pid, int uid) {
3332        int i = mProcessObservers.beginBroadcast();
3333        while (i > 0) {
3334            i--;
3335            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3336            if (observer != null) {
3337                try {
3338                    observer.onProcessDied(pid, uid);
3339                } catch (RemoteException e) {
3340                }
3341            }
3342        }
3343        mProcessObservers.finishBroadcast();
3344    }
3345
3346    @Override
3347    public final int startActivity(IApplicationThread caller, String callingPackage,
3348            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3349            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3350        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3351            resultWho, requestCode, startFlags, profilerInfo, options,
3352            UserHandle.getCallingUserId());
3353    }
3354
3355    @Override
3356    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3357            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3358            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3359        enforceNotIsolatedCaller("startActivity");
3360        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3361                false, ALLOW_FULL_ONLY, "startActivity", null);
3362        // TODO: Switch to user app stacks here.
3363        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3364                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3365                profilerInfo, null, null, options, userId, null, null);
3366    }
3367
3368    @Override
3369    public final int startActivityAsCaller(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
3373        // This is very dangerous -- it allows you to perform a start activity (including
3374        // permission grants) as any app that may launch one of your own activities.  So
3375        // we will only allow this to be done from activities that are part of the core framework,
3376        // and then only when they are running as the system.
3377        final ActivityRecord sourceRecord;
3378        final int targetUid;
3379        final String targetPackage;
3380        synchronized (this) {
3381            if (resultTo == null) {
3382                throw new SecurityException("Must be called from an activity");
3383            }
3384            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3385            if (sourceRecord == null) {
3386                throw new SecurityException("Called with bad activity token: " + resultTo);
3387            }
3388            if (!sourceRecord.info.packageName.equals("android")) {
3389                throw new SecurityException(
3390                        "Must be called from an activity that is declared in the android package");
3391            }
3392            if (sourceRecord.app == null) {
3393                throw new SecurityException("Called without a process attached to activity");
3394            }
3395            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3396                // This is still okay, as long as this activity is running under the
3397                // uid of the original calling activity.
3398                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3399                    throw new SecurityException(
3400                            "Calling activity in uid " + sourceRecord.app.uid
3401                                    + " must be system uid or original calling uid "
3402                                    + sourceRecord.launchedFromUid);
3403                }
3404            }
3405            targetUid = sourceRecord.launchedFromUid;
3406            targetPackage = sourceRecord.launchedFromPackage;
3407        }
3408
3409        if (userId == UserHandle.USER_NULL) {
3410            userId = UserHandle.getUserId(sourceRecord.app.uid);
3411        }
3412
3413        // TODO: Switch to user app stacks here.
3414        try {
3415            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3416                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3417                    null, null, options, userId, null, null);
3418            return ret;
3419        } catch (SecurityException e) {
3420            // XXX need to figure out how to propagate to original app.
3421            // A SecurityException here is generally actually a fault of the original
3422            // calling activity (such as a fairly granting permissions), so propagate it
3423            // back to them.
3424            /*
3425            StringBuilder msg = new StringBuilder();
3426            msg.append("While launching");
3427            msg.append(intent.toString());
3428            msg.append(": ");
3429            msg.append(e.getMessage());
3430            */
3431            throw e;
3432        }
3433    }
3434
3435    @Override
3436    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3437            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3438            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3439        enforceNotIsolatedCaller("startActivityAndWait");
3440        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3441                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3442        WaitResult res = new WaitResult();
3443        // TODO: Switch to user app stacks here.
3444        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3445                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3446                options, userId, null, null);
3447        return res;
3448    }
3449
3450    @Override
3451    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3452            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3453            int startFlags, Configuration config, Bundle options, int userId) {
3454        enforceNotIsolatedCaller("startActivityWithConfig");
3455        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3456                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3457        // TODO: Switch to user app stacks here.
3458        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3459                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3460                null, null, config, options, userId, null, null);
3461        return ret;
3462    }
3463
3464    @Override
3465    public int startActivityIntentSender(IApplicationThread caller,
3466            IntentSender intent, Intent fillInIntent, String resolvedType,
3467            IBinder resultTo, String resultWho, int requestCode,
3468            int flagsMask, int flagsValues, Bundle options) {
3469        enforceNotIsolatedCaller("startActivityIntentSender");
3470        // Refuse possible leaked file descriptors
3471        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3472            throw new IllegalArgumentException("File descriptors passed in Intent");
3473        }
3474
3475        IIntentSender sender = intent.getTarget();
3476        if (!(sender instanceof PendingIntentRecord)) {
3477            throw new IllegalArgumentException("Bad PendingIntent object");
3478        }
3479
3480        PendingIntentRecord pir = (PendingIntentRecord)sender;
3481
3482        synchronized (this) {
3483            // If this is coming from the currently resumed activity, it is
3484            // effectively saying that app switches are allowed at this point.
3485            final ActivityStack stack = getFocusedStack();
3486            if (stack.mResumedActivity != null &&
3487                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3488                mAppSwitchesAllowedTime = 0;
3489            }
3490        }
3491        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3492                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3493        return ret;
3494    }
3495
3496    @Override
3497    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3498            Intent intent, String resolvedType, IVoiceInteractionSession session,
3499            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3500            Bundle options, int userId) {
3501        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3502                != PackageManager.PERMISSION_GRANTED) {
3503            String msg = "Permission Denial: startVoiceActivity() from pid="
3504                    + Binder.getCallingPid()
3505                    + ", uid=" + Binder.getCallingUid()
3506                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3507            Slog.w(TAG, msg);
3508            throw new SecurityException(msg);
3509        }
3510        if (session == null || interactor == null) {
3511            throw new NullPointerException("null session or interactor");
3512        }
3513        userId = handleIncomingUser(callingPid, callingUid, userId,
3514                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3515        // TODO: Switch to user app stacks here.
3516        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3517                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3518                null, options, userId, null, null);
3519    }
3520
3521    @Override
3522    public boolean startNextMatchingActivity(IBinder callingActivity,
3523            Intent intent, Bundle options) {
3524        // Refuse possible leaked file descriptors
3525        if (intent != null && intent.hasFileDescriptors() == true) {
3526            throw new IllegalArgumentException("File descriptors passed in Intent");
3527        }
3528
3529        synchronized (this) {
3530            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3531            if (r == null) {
3532                ActivityOptions.abort(options);
3533                return false;
3534            }
3535            if (r.app == null || r.app.thread == null) {
3536                // The caller is not running...  d'oh!
3537                ActivityOptions.abort(options);
3538                return false;
3539            }
3540            intent = new Intent(intent);
3541            // The caller is not allowed to change the data.
3542            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3543            // And we are resetting to find the next component...
3544            intent.setComponent(null);
3545
3546            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3547
3548            ActivityInfo aInfo = null;
3549            try {
3550                List<ResolveInfo> resolves =
3551                    AppGlobals.getPackageManager().queryIntentActivities(
3552                            intent, r.resolvedType,
3553                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3554                            UserHandle.getCallingUserId());
3555
3556                // Look for the original activity in the list...
3557                final int N = resolves != null ? resolves.size() : 0;
3558                for (int i=0; i<N; i++) {
3559                    ResolveInfo rInfo = resolves.get(i);
3560                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3561                            && rInfo.activityInfo.name.equals(r.info.name)) {
3562                        // We found the current one...  the next matching is
3563                        // after it.
3564                        i++;
3565                        if (i<N) {
3566                            aInfo = resolves.get(i).activityInfo;
3567                        }
3568                        if (debug) {
3569                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3570                                    + "/" + r.info.name);
3571                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3572                                    + "/" + aInfo.name);
3573                        }
3574                        break;
3575                    }
3576                }
3577            } catch (RemoteException e) {
3578            }
3579
3580            if (aInfo == null) {
3581                // Nobody who is next!
3582                ActivityOptions.abort(options);
3583                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3584                return false;
3585            }
3586
3587            intent.setComponent(new ComponentName(
3588                    aInfo.applicationInfo.packageName, aInfo.name));
3589            intent.setFlags(intent.getFlags()&~(
3590                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3591                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3592                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3593                    Intent.FLAG_ACTIVITY_NEW_TASK));
3594
3595            // Okay now we need to start the new activity, replacing the
3596            // currently running activity.  This is a little tricky because
3597            // we want to start the new one as if the current one is finished,
3598            // but not finish the current one first so that there is no flicker.
3599            // And thus...
3600            final boolean wasFinishing = r.finishing;
3601            r.finishing = true;
3602
3603            // Propagate reply information over to the new activity.
3604            final ActivityRecord resultTo = r.resultTo;
3605            final String resultWho = r.resultWho;
3606            final int requestCode = r.requestCode;
3607            r.resultTo = null;
3608            if (resultTo != null) {
3609                resultTo.removeResultsLocked(r, resultWho, requestCode);
3610            }
3611
3612            final long origId = Binder.clearCallingIdentity();
3613            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3614                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3615                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3616                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3617            Binder.restoreCallingIdentity(origId);
3618
3619            r.finishing = wasFinishing;
3620            if (res != ActivityManager.START_SUCCESS) {
3621                return false;
3622            }
3623            return true;
3624        }
3625    }
3626
3627    @Override
3628    public final int startActivityFromRecents(int taskId, Bundle options) {
3629        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3630            String msg = "Permission Denial: startActivityFromRecents called without " +
3631                    START_TASKS_FROM_RECENTS;
3632            Slog.w(TAG, msg);
3633            throw new SecurityException(msg);
3634        }
3635        return startActivityFromRecentsInner(taskId, options);
3636    }
3637
3638    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3639        final TaskRecord task;
3640        final int callingUid;
3641        final String callingPackage;
3642        final Intent intent;
3643        final int userId;
3644        synchronized (this) {
3645            task = recentTaskForIdLocked(taskId);
3646            if (task == null) {
3647                throw new IllegalArgumentException("Task " + taskId + " not found.");
3648            }
3649            if (task.getRootActivity() != null) {
3650                moveTaskToFrontLocked(task.taskId, 0, null);
3651                return ActivityManager.START_TASK_TO_FRONT;
3652            }
3653            callingUid = task.mCallingUid;
3654            callingPackage = task.mCallingPackage;
3655            intent = task.intent;
3656            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3657            userId = task.userId;
3658        }
3659        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3660                options, userId, null, task);
3661    }
3662
3663    final int startActivityInPackage(int uid, String callingPackage,
3664            Intent intent, String resolvedType, IBinder resultTo,
3665            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3666            IActivityContainer container, TaskRecord inTask) {
3667
3668        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3669                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3670
3671        // TODO: Switch to user app stacks here.
3672        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3673                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3674                null, null, null, options, userId, container, inTask);
3675        return ret;
3676    }
3677
3678    @Override
3679    public final int startActivities(IApplicationThread caller, String callingPackage,
3680            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3681            int userId) {
3682        enforceNotIsolatedCaller("startActivities");
3683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3684                false, ALLOW_FULL_ONLY, "startActivity", null);
3685        // TODO: Switch to user app stacks here.
3686        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3687                resolvedTypes, resultTo, options, userId);
3688        return ret;
3689    }
3690
3691    final int startActivitiesInPackage(int uid, String callingPackage,
3692            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3693            Bundle options, int userId) {
3694
3695        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3696                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3697        // TODO: Switch to user app stacks here.
3698        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3699                resultTo, options, userId);
3700        return ret;
3701    }
3702
3703    //explicitly remove thd old information in mRecentTasks when removing existing user.
3704    private void removeRecentTasksForUserLocked(int userId) {
3705        if(userId <= 0) {
3706            Slog.i(TAG, "Can't remove recent task on user " + userId);
3707            return;
3708        }
3709
3710        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3711            TaskRecord tr = mRecentTasks.get(i);
3712            if (tr.userId == userId) {
3713                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3714                        + " when finishing user" + userId);
3715                mRecentTasks.remove(i);
3716                tr.removedFromRecents();
3717            }
3718        }
3719
3720        // Remove tasks from persistent storage.
3721        notifyTaskPersisterLocked(null, true);
3722    }
3723
3724    // Sort by taskId
3725    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3726        @Override
3727        public int compare(TaskRecord lhs, TaskRecord rhs) {
3728            return rhs.taskId - lhs.taskId;
3729        }
3730    };
3731
3732    // Extract the affiliates of the chain containing mRecentTasks[start].
3733    private int processNextAffiliateChainLocked(int start) {
3734        final TaskRecord startTask = mRecentTasks.get(start);
3735        final int affiliateId = startTask.mAffiliatedTaskId;
3736
3737        // Quick identification of isolated tasks. I.e. those not launched behind.
3738        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3739                startTask.mNextAffiliate == null) {
3740            // There is still a slim chance that there are other tasks that point to this task
3741            // and that the chain is so messed up that this task no longer points to them but
3742            // the gain of this optimization outweighs the risk.
3743            startTask.inRecents = true;
3744            return start + 1;
3745        }
3746
3747        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3748        mTmpRecents.clear();
3749        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3750            final TaskRecord task = mRecentTasks.get(i);
3751            if (task.mAffiliatedTaskId == affiliateId) {
3752                mRecentTasks.remove(i);
3753                mTmpRecents.add(task);
3754            }
3755        }
3756
3757        // Sort them all by taskId. That is the order they were create in and that order will
3758        // always be correct.
3759        Collections.sort(mTmpRecents, mTaskRecordComparator);
3760
3761        // Go through and fix up the linked list.
3762        // The first one is the end of the chain and has no next.
3763        final TaskRecord first = mTmpRecents.get(0);
3764        first.inRecents = true;
3765        if (first.mNextAffiliate != null) {
3766            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3767            first.setNextAffiliate(null);
3768            notifyTaskPersisterLocked(first, false);
3769        }
3770        // Everything in the middle is doubly linked from next to prev.
3771        final int tmpSize = mTmpRecents.size();
3772        for (int i = 0; i < tmpSize - 1; ++i) {
3773            final TaskRecord next = mTmpRecents.get(i);
3774            final TaskRecord prev = mTmpRecents.get(i + 1);
3775            if (next.mPrevAffiliate != prev) {
3776                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3777                        " setting prev=" + prev);
3778                next.setPrevAffiliate(prev);
3779                notifyTaskPersisterLocked(next, false);
3780            }
3781            if (prev.mNextAffiliate != next) {
3782                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3783                        " setting next=" + next);
3784                prev.setNextAffiliate(next);
3785                notifyTaskPersisterLocked(prev, false);
3786            }
3787            prev.inRecents = true;
3788        }
3789        // The last one is the beginning of the list and has no prev.
3790        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3791        if (last.mPrevAffiliate != null) {
3792            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3793            last.setPrevAffiliate(null);
3794            notifyTaskPersisterLocked(last, false);
3795        }
3796
3797        // Insert the group back into mRecentTasks at start.
3798        mRecentTasks.addAll(start, mTmpRecents);
3799
3800        // Let the caller know where we left off.
3801        return start + tmpSize;
3802    }
3803
3804    /**
3805     * Update the recent tasks lists: make sure tasks should still be here (their
3806     * applications / activities still exist), update their availability, fixup ordering
3807     * of affiliations.
3808     */
3809    void cleanupRecentTasksLocked(int userId) {
3810        if (mRecentTasks == null) {
3811            // Happens when called from the packagemanager broadcast before boot.
3812            return;
3813        }
3814
3815        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3816        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3817        final IPackageManager pm = AppGlobals.getPackageManager();
3818        final ActivityInfo dummyAct = new ActivityInfo();
3819        final ApplicationInfo dummyApp = new ApplicationInfo();
3820
3821        int N = mRecentTasks.size();
3822
3823        int[] users = userId == UserHandle.USER_ALL
3824                ? getUsersLocked() : new int[] { userId };
3825        for (int user : users) {
3826            for (int i = 0; i < N; i++) {
3827                TaskRecord task = mRecentTasks.get(i);
3828                if (task.userId != user) {
3829                    // Only look at tasks for the user ID of interest.
3830                    continue;
3831                }
3832                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3833                    // This situation is broken, and we should just get rid of it now.
3834                    mRecentTasks.remove(i);
3835                    task.removedFromRecents();
3836                    i--;
3837                    N--;
3838                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3839                    continue;
3840                }
3841                // Check whether this activity is currently available.
3842                if (task.realActivity != null) {
3843                    ActivityInfo ai = availActCache.get(task.realActivity);
3844                    if (ai == null) {
3845                        try {
3846                            ai = pm.getActivityInfo(task.realActivity,
3847                                    PackageManager.GET_UNINSTALLED_PACKAGES
3848                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3849                        } catch (RemoteException e) {
3850                            // Will never happen.
3851                            continue;
3852                        }
3853                        if (ai == null) {
3854                            ai = dummyAct;
3855                        }
3856                        availActCache.put(task.realActivity, ai);
3857                    }
3858                    if (ai == dummyAct) {
3859                        // This could be either because the activity no longer exists, or the
3860                        // app is temporarily gone.  For the former we want to remove the recents
3861                        // entry; for the latter we want to mark it as unavailable.
3862                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3863                        if (app == null) {
3864                            try {
3865                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3866                                        PackageManager.GET_UNINSTALLED_PACKAGES
3867                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3868                            } catch (RemoteException e) {
3869                                // Will never happen.
3870                                continue;
3871                            }
3872                            if (app == null) {
3873                                app = dummyApp;
3874                            }
3875                            availAppCache.put(task.realActivity.getPackageName(), app);
3876                        }
3877                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3878                            // Doesn't exist any more!  Good-bye.
3879                            mRecentTasks.remove(i);
3880                            task.removedFromRecents();
3881                            i--;
3882                            N--;
3883                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3884                            continue;
3885                        } else {
3886                            // Otherwise just not available for now.
3887                            if (task.isAvailable) {
3888                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3889                                        + task);
3890                            }
3891                            task.isAvailable = false;
3892                        }
3893                    } else {
3894                        if (!ai.enabled || !ai.applicationInfo.enabled
3895                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3896                            if (task.isAvailable) {
3897                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3898                                        + task + " (enabled=" + ai.enabled + "/"
3899                                        + ai.applicationInfo.enabled +  " flags="
3900                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3901                            }
3902                            task.isAvailable = false;
3903                        } else {
3904                            if (!task.isAvailable) {
3905                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3906                                        + task);
3907                            }
3908                            task.isAvailable = true;
3909                        }
3910                    }
3911                }
3912            }
3913        }
3914
3915        // Verify the affiliate chain for each task.
3916        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3917        }
3918
3919        mTmpRecents.clear();
3920        // mRecentTasks is now in sorted, affiliated order.
3921    }
3922
3923    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3924        int N = mRecentTasks.size();
3925        TaskRecord top = task;
3926        int topIndex = taskIndex;
3927        while (top.mNextAffiliate != null && topIndex > 0) {
3928            top = top.mNextAffiliate;
3929            topIndex--;
3930        }
3931        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3932                + topIndex + " from intial " + taskIndex);
3933        // Find the end of the chain, doing a sanity check along the way.
3934        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3935        int endIndex = topIndex;
3936        TaskRecord prev = top;
3937        while (endIndex < N) {
3938            TaskRecord cur = mRecentTasks.get(endIndex);
3939            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3940                    + endIndex + " " + cur);
3941            if (cur == top) {
3942                // Verify start of the chain.
3943                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3944                    Slog.wtf(TAG, "Bad chain @" + endIndex
3945                            + ": first task has next affiliate: " + prev);
3946                    sane = false;
3947                    break;
3948                }
3949            } else {
3950                // Verify middle of the chain's next points back to the one before.
3951                if (cur.mNextAffiliate != prev
3952                        || cur.mNextAffiliateTaskId != prev.taskId) {
3953                    Slog.wtf(TAG, "Bad chain @" + endIndex
3954                            + ": middle task " + cur + " @" + endIndex
3955                            + " has bad next affiliate "
3956                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3957                            + ", expected " + prev);
3958                    sane = false;
3959                    break;
3960                }
3961            }
3962            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3963                // Chain ends here.
3964                if (cur.mPrevAffiliate != null) {
3965                    Slog.wtf(TAG, "Bad chain @" + endIndex
3966                            + ": last task " + cur + " has previous affiliate "
3967                            + cur.mPrevAffiliate);
3968                    sane = false;
3969                }
3970                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3971                break;
3972            } else {
3973                // Verify middle of the chain's prev points to a valid item.
3974                if (cur.mPrevAffiliate == null) {
3975                    Slog.wtf(TAG, "Bad chain @" + endIndex
3976                            + ": task " + cur + " has previous affiliate "
3977                            + cur.mPrevAffiliate + " but should be id "
3978                            + cur.mPrevAffiliate);
3979                    sane = false;
3980                    break;
3981                }
3982            }
3983            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3984                Slog.wtf(TAG, "Bad chain @" + endIndex
3985                        + ": task " + cur + " has affiliated id "
3986                        + cur.mAffiliatedTaskId + " but should be "
3987                        + task.mAffiliatedTaskId);
3988                sane = false;
3989                break;
3990            }
3991            prev = cur;
3992            endIndex++;
3993            if (endIndex >= N) {
3994                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3995                        + ": last task " + prev);
3996                sane = false;
3997                break;
3998            }
3999        }
4000        if (sane) {
4001            if (endIndex < taskIndex) {
4002                Slog.wtf(TAG, "Bad chain @" + endIndex
4003                        + ": did not extend to task " + task + " @" + taskIndex);
4004                sane = false;
4005            }
4006        }
4007        if (sane) {
4008            // All looks good, we can just move all of the affiliated tasks
4009            // to the top.
4010            for (int i=topIndex; i<=endIndex; i++) {
4011                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4012                        + " from " + i + " to " + (i-topIndex));
4013                TaskRecord cur = mRecentTasks.remove(i);
4014                mRecentTasks.add(i-topIndex, cur);
4015            }
4016            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4017                    + " to " + endIndex);
4018            return true;
4019        }
4020
4021        // Whoops, couldn't do it.
4022        return false;
4023    }
4024
4025    final void addRecentTaskLocked(TaskRecord task) {
4026        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4027                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4028                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4029
4030        int N = mRecentTasks.size();
4031        // Quick case: check if the top-most recent task is the same.
4032        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4033            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4034            return;
4035        }
4036        // Another quick case: check if this is part of a set of affiliated
4037        // tasks that are at the top.
4038        if (isAffiliated && N > 0 && task.inRecents
4039                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4040            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4041                    + " at top when adding " + task);
4042            return;
4043        }
4044        // Another quick case: never add voice sessions.
4045        if (task.voiceSession != null) {
4046            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4047            return;
4048        }
4049
4050        boolean needAffiliationFix = false;
4051
4052        // Slightly less quick case: the task is already in recents, so all we need
4053        // to do is move it.
4054        if (task.inRecents) {
4055            int taskIndex = mRecentTasks.indexOf(task);
4056            if (taskIndex >= 0) {
4057                if (!isAffiliated) {
4058                    // Simple case: this is not an affiliated task, so we just move it to the front.
4059                    mRecentTasks.remove(taskIndex);
4060                    mRecentTasks.add(0, task);
4061                    notifyTaskPersisterLocked(task, false);
4062                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4063                            + " from " + taskIndex);
4064                    return;
4065                } else {
4066                    // More complicated: need to keep all affiliated tasks together.
4067                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4068                        // All went well.
4069                        return;
4070                    }
4071
4072                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4073                    // everything and then go through our general path of adding a new task.
4074                    needAffiliationFix = true;
4075                }
4076            } else {
4077                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4078                needAffiliationFix = true;
4079            }
4080        }
4081
4082        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4083        trimRecentsForTaskLocked(task, true);
4084
4085        N = mRecentTasks.size();
4086        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4087            final TaskRecord tr = mRecentTasks.remove(N - 1);
4088            tr.removedFromRecents();
4089            N--;
4090        }
4091        task.inRecents = true;
4092        if (!isAffiliated || needAffiliationFix) {
4093            // If this is a simple non-affiliated task, or we had some failure trying to
4094            // handle it as part of an affilated task, then just place it at the top.
4095            mRecentTasks.add(0, task);
4096        } else if (isAffiliated) {
4097            // If this is a new affiliated task, then move all of the affiliated tasks
4098            // to the front and insert this new one.
4099            TaskRecord other = task.mNextAffiliate;
4100            if (other == null) {
4101                other = task.mPrevAffiliate;
4102            }
4103            if (other != null) {
4104                int otherIndex = mRecentTasks.indexOf(other);
4105                if (otherIndex >= 0) {
4106                    // Insert new task at appropriate location.
4107                    int taskIndex;
4108                    if (other == task.mNextAffiliate) {
4109                        // We found the index of our next affiliation, which is who is
4110                        // before us in the list, so add after that point.
4111                        taskIndex = otherIndex+1;
4112                    } else {
4113                        // We found the index of our previous affiliation, which is who is
4114                        // after us in the list, so add at their position.
4115                        taskIndex = otherIndex;
4116                    }
4117                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4118                            + taskIndex + ": " + task);
4119                    mRecentTasks.add(taskIndex, task);
4120
4121                    // Now move everything to the front.
4122                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4123                        // All went well.
4124                        return;
4125                    }
4126
4127                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4128                    // everything and then go through our general path of adding a new task.
4129                    needAffiliationFix = true;
4130                } else {
4131                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4132                            + other);
4133                    needAffiliationFix = true;
4134                }
4135            } else {
4136                if (DEBUG_RECENTS) Slog.d(TAG,
4137                        "addRecent: adding affiliated task without next/prev:" + task);
4138                needAffiliationFix = true;
4139            }
4140        }
4141        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4142
4143        if (needAffiliationFix) {
4144            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4145            cleanupRecentTasksLocked(task.userId);
4146        }
4147    }
4148
4149    /**
4150     * If needed, remove oldest existing entries in recents that are for the same kind
4151     * of task as the given one.
4152     */
4153    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4154        int N = mRecentTasks.size();
4155        final Intent intent = task.intent;
4156        final boolean document = intent != null && intent.isDocument();
4157
4158        int maxRecents = task.maxRecents - 1;
4159        for (int i=0; i<N; i++) {
4160            final TaskRecord tr = mRecentTasks.get(i);
4161            if (task != tr) {
4162                if (task.userId != tr.userId) {
4163                    continue;
4164                }
4165                if (i > MAX_RECENT_BITMAPS) {
4166                    tr.freeLastThumbnail();
4167                }
4168                final Intent trIntent = tr.intent;
4169                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4170                    (intent == null || !intent.filterEquals(trIntent))) {
4171                    continue;
4172                }
4173                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4174                if (document && trIsDocument) {
4175                    // These are the same document activity (not necessarily the same doc).
4176                    if (maxRecents > 0) {
4177                        --maxRecents;
4178                        continue;
4179                    }
4180                    // Hit the maximum number of documents for this task. Fall through
4181                    // and remove this document from recents.
4182                } else if (document || trIsDocument) {
4183                    // Only one of these is a document. Not the droid we're looking for.
4184                    continue;
4185                }
4186            }
4187
4188            if (!doTrim) {
4189                // If the caller is not actually asking for a trim, just tell them we reached
4190                // a point where the trim would happen.
4191                return i;
4192            }
4193
4194            // Either task and tr are the same or, their affinities match or their intents match
4195            // and neither of them is a document, or they are documents using the same activity
4196            // and their maxRecents has been reached.
4197            tr.disposeThumbnail();
4198            mRecentTasks.remove(i);
4199            if (task != tr) {
4200                tr.removedFromRecents();
4201            }
4202            i--;
4203            N--;
4204            if (task.intent == null) {
4205                // If the new recent task we are adding is not fully
4206                // specified, then replace it with the existing recent task.
4207                task = tr;
4208            }
4209            notifyTaskPersisterLocked(tr, false);
4210        }
4211
4212        return -1;
4213    }
4214
4215    @Override
4216    public void reportActivityFullyDrawn(IBinder token) {
4217        synchronized (this) {
4218            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219            if (r == null) {
4220                return;
4221            }
4222            r.reportFullyDrawnLocked();
4223        }
4224    }
4225
4226    @Override
4227    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4228        synchronized (this) {
4229            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4230            if (r == null) {
4231                return;
4232            }
4233            final long origId = Binder.clearCallingIdentity();
4234            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4235            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4236                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4237            if (config != null) {
4238                r.frozenBeforeDestroy = true;
4239                if (!updateConfigurationLocked(config, r, false, false)) {
4240                    mStackSupervisor.resumeTopActivitiesLocked();
4241                }
4242            }
4243            Binder.restoreCallingIdentity(origId);
4244        }
4245    }
4246
4247    @Override
4248    public int getRequestedOrientation(IBinder token) {
4249        synchronized (this) {
4250            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4251            if (r == null) {
4252                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4253            }
4254            return mWindowManager.getAppOrientation(r.appToken);
4255        }
4256    }
4257
4258    /**
4259     * This is the internal entry point for handling Activity.finish().
4260     *
4261     * @param token The Binder token referencing the Activity we want to finish.
4262     * @param resultCode Result code, if any, from this Activity.
4263     * @param resultData Result data (Intent), if any, from this Activity.
4264     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4265     *            the root Activity in the task.
4266     *
4267     * @return Returns true if the activity successfully finished, or false if it is still running.
4268     */
4269    @Override
4270    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4271            boolean finishTask) {
4272        // Refuse possible leaked file descriptors
4273        if (resultData != null && resultData.hasFileDescriptors() == true) {
4274            throw new IllegalArgumentException("File descriptors passed in Intent");
4275        }
4276
4277        synchronized(this) {
4278            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4279            if (r == null) {
4280                return true;
4281            }
4282            // Keep track of the root activity of the task before we finish it
4283            TaskRecord tr = r.task;
4284            ActivityRecord rootR = tr.getRootActivity();
4285            if (rootR == null) {
4286                Slog.w(TAG, "Finishing task with all activities already finished");
4287            }
4288            // Do not allow task to finish in Lock Task mode.
4289            if (tr == mStackSupervisor.mLockTaskModeTask) {
4290                if (rootR == r) {
4291                    Slog.i(TAG, "Not finishing task in lock task mode");
4292                    mStackSupervisor.showLockTaskToast();
4293                    return false;
4294                }
4295            }
4296            if (mController != null) {
4297                // Find the first activity that is not finishing.
4298                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4299                if (next != null) {
4300                    // ask watcher if this is allowed
4301                    boolean resumeOK = true;
4302                    try {
4303                        resumeOK = mController.activityResuming(next.packageName);
4304                    } catch (RemoteException e) {
4305                        mController = null;
4306                        Watchdog.getInstance().setActivityController(null);
4307                    }
4308
4309                    if (!resumeOK) {
4310                        Slog.i(TAG, "Not finishing activity because controller resumed");
4311                        return false;
4312                    }
4313                }
4314            }
4315            final long origId = Binder.clearCallingIdentity();
4316            try {
4317                boolean res;
4318                if (finishTask && r == rootR) {
4319                    // If requested, remove the task that is associated to this activity only if it
4320                    // was the root activity in the task. The result code and data is ignored
4321                    // because we don't support returning them across task boundaries.
4322                    res = removeTaskByIdLocked(tr.taskId, false);
4323                    if (!res) {
4324                        Slog.i(TAG, "Removing task failed to finish activity");
4325                    }
4326                } else {
4327                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4328                            resultData, "app-request", true);
4329                    if (!res) {
4330                        Slog.i(TAG, "Failed to finish by app-request");
4331                    }
4332                }
4333                return res;
4334            } finally {
4335                Binder.restoreCallingIdentity(origId);
4336            }
4337        }
4338    }
4339
4340    @Override
4341    public final void finishHeavyWeightApp() {
4342        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351
4352        synchronized(this) {
4353            if (mHeavyWeightProcess == null) {
4354                return;
4355            }
4356
4357            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4358                    mHeavyWeightProcess.activities);
4359            for (int i=0; i<activities.size(); i++) {
4360                ActivityRecord r = activities.get(i);
4361                if (!r.finishing) {
4362                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4363                            null, "finish-heavy", true);
4364                }
4365            }
4366
4367            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4368                    mHeavyWeightProcess.userId, 0));
4369            mHeavyWeightProcess = null;
4370        }
4371    }
4372
4373    @Override
4374    public void crashApplication(int uid, int initialPid, String packageName,
4375            String message) {
4376        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4377                != PackageManager.PERMISSION_GRANTED) {
4378            String msg = "Permission Denial: crashApplication() from pid="
4379                    + Binder.getCallingPid()
4380                    + ", uid=" + Binder.getCallingUid()
4381                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4382            Slog.w(TAG, msg);
4383            throw new SecurityException(msg);
4384        }
4385
4386        synchronized(this) {
4387            ProcessRecord proc = null;
4388
4389            // Figure out which process to kill.  We don't trust that initialPid
4390            // still has any relation to current pids, so must scan through the
4391            // list.
4392            synchronized (mPidsSelfLocked) {
4393                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4394                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4395                    if (p.uid != uid) {
4396                        continue;
4397                    }
4398                    if (p.pid == initialPid) {
4399                        proc = p;
4400                        break;
4401                    }
4402                    if (p.pkgList.containsKey(packageName)) {
4403                        proc = p;
4404                    }
4405                }
4406            }
4407
4408            if (proc == null) {
4409                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4410                        + " initialPid=" + initialPid
4411                        + " packageName=" + packageName);
4412                return;
4413            }
4414
4415            if (proc.thread != null) {
4416                if (proc.pid == Process.myPid()) {
4417                    Log.w(TAG, "crashApplication: trying to crash self!");
4418                    return;
4419                }
4420                long ident = Binder.clearCallingIdentity();
4421                try {
4422                    proc.thread.scheduleCrash(message);
4423                } catch (RemoteException e) {
4424                }
4425                Binder.restoreCallingIdentity(ident);
4426            }
4427        }
4428    }
4429
4430    @Override
4431    public final void finishSubActivity(IBinder token, String resultWho,
4432            int requestCode) {
4433        synchronized(this) {
4434            final long origId = Binder.clearCallingIdentity();
4435            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4436            if (r != null) {
4437                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4438            }
4439            Binder.restoreCallingIdentity(origId);
4440        }
4441    }
4442
4443    @Override
4444    public boolean finishActivityAffinity(IBinder token) {
4445        synchronized(this) {
4446            final long origId = Binder.clearCallingIdentity();
4447            try {
4448                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4449
4450                ActivityRecord rootR = r.task.getRootActivity();
4451                // Do not allow task to finish in Lock Task mode.
4452                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4453                    if (rootR == r) {
4454                        mStackSupervisor.showLockTaskToast();
4455                        return false;
4456                    }
4457                }
4458                boolean res = false;
4459                if (r != null) {
4460                    res = r.task.stack.finishActivityAffinityLocked(r);
4461                }
4462                return res;
4463            } finally {
4464                Binder.restoreCallingIdentity(origId);
4465            }
4466        }
4467    }
4468
4469    @Override
4470    public void finishVoiceTask(IVoiceInteractionSession session) {
4471        synchronized(this) {
4472            final long origId = Binder.clearCallingIdentity();
4473            try {
4474                mStackSupervisor.finishVoiceTask(session);
4475            } finally {
4476                Binder.restoreCallingIdentity(origId);
4477            }
4478        }
4479
4480    }
4481
4482    @Override
4483    public boolean releaseActivityInstance(IBinder token) {
4484        synchronized(this) {
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4488                if (r.task == null || r.task.stack == null) {
4489                    return false;
4490                }
4491                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4492            } finally {
4493                Binder.restoreCallingIdentity(origId);
4494            }
4495        }
4496    }
4497
4498    @Override
4499    public void releaseSomeActivities(IApplicationThread appInt) {
4500        synchronized(this) {
4501            final long origId = Binder.clearCallingIdentity();
4502            try {
4503                ProcessRecord app = getRecordForAppLocked(appInt);
4504                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4505            } finally {
4506                Binder.restoreCallingIdentity(origId);
4507            }
4508        }
4509    }
4510
4511    @Override
4512    public boolean willActivityBeVisible(IBinder token) {
4513        synchronized(this) {
4514            ActivityStack stack = ActivityRecord.getStackLocked(token);
4515            if (stack != null) {
4516                return stack.willActivityBeVisibleLocked(token);
4517            }
4518            return false;
4519        }
4520    }
4521
4522    @Override
4523    public void overridePendingTransition(IBinder token, String packageName,
4524            int enterAnim, int exitAnim) {
4525        synchronized(this) {
4526            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4527            if (self == null) {
4528                return;
4529            }
4530
4531            final long origId = Binder.clearCallingIdentity();
4532
4533            if (self.state == ActivityState.RESUMED
4534                    || self.state == ActivityState.PAUSING) {
4535                mWindowManager.overridePendingAppTransition(packageName,
4536                        enterAnim, exitAnim, null);
4537            }
4538
4539            Binder.restoreCallingIdentity(origId);
4540        }
4541    }
4542
4543    /**
4544     * Main function for removing an existing process from the activity manager
4545     * as a result of that process going away.  Clears out all connections
4546     * to the process.
4547     */
4548    private final void handleAppDiedLocked(ProcessRecord app,
4549            boolean restarting, boolean allowRestart) {
4550        int pid = app.pid;
4551        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4552        if (!kept && !restarting) {
4553            removeLruProcessLocked(app);
4554            if (pid > 0) {
4555                ProcessList.remove(pid);
4556            }
4557        }
4558
4559        if (mProfileProc == app) {
4560            clearProfilerLocked();
4561        }
4562
4563        // Remove this application's activities from active lists.
4564        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4565
4566        app.activities.clear();
4567
4568        if (app.instrumentationClass != null) {
4569            Slog.w(TAG, "Crash of app " + app.processName
4570                  + " running instrumentation " + app.instrumentationClass);
4571            Bundle info = new Bundle();
4572            info.putString("shortMsg", "Process crashed.");
4573            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4574        }
4575
4576        if (!restarting) {
4577            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4578                // If there was nothing to resume, and we are not already
4579                // restarting this process, but there is a visible activity that
4580                // is hosted by the process...  then make sure all visible
4581                // activities are running, taking care of restarting this
4582                // process.
4583                if (hasVisibleActivities) {
4584                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4585                }
4586            }
4587        }
4588    }
4589
4590    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4591        IBinder threadBinder = thread.asBinder();
4592        // Find the application record.
4593        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4594            ProcessRecord rec = mLruProcesses.get(i);
4595            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4596                return i;
4597            }
4598        }
4599        return -1;
4600    }
4601
4602    final ProcessRecord getRecordForAppLocked(
4603            IApplicationThread thread) {
4604        if (thread == null) {
4605            return null;
4606        }
4607
4608        int appIndex = getLRURecordIndexForAppLocked(thread);
4609        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4610    }
4611
4612    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4613        // If there are no longer any background processes running,
4614        // and the app that died was not running instrumentation,
4615        // then tell everyone we are now low on memory.
4616        boolean haveBg = false;
4617        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4618            ProcessRecord rec = mLruProcesses.get(i);
4619            if (rec.thread != null
4620                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4621                haveBg = true;
4622                break;
4623            }
4624        }
4625
4626        if (!haveBg) {
4627            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4628            if (doReport) {
4629                long now = SystemClock.uptimeMillis();
4630                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4631                    doReport = false;
4632                } else {
4633                    mLastMemUsageReportTime = now;
4634                }
4635            }
4636            final ArrayList<ProcessMemInfo> memInfos
4637                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4638            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4639            long now = SystemClock.uptimeMillis();
4640            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4641                ProcessRecord rec = mLruProcesses.get(i);
4642                if (rec == dyingProc || rec.thread == null) {
4643                    continue;
4644                }
4645                if (doReport) {
4646                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4647                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4648                }
4649                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4650                    // The low memory report is overriding any current
4651                    // state for a GC request.  Make sure to do
4652                    // heavy/important/visible/foreground processes first.
4653                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4654                        rec.lastRequestedGc = 0;
4655                    } else {
4656                        rec.lastRequestedGc = rec.lastLowMemory;
4657                    }
4658                    rec.reportLowMemory = true;
4659                    rec.lastLowMemory = now;
4660                    mProcessesToGc.remove(rec);
4661                    addProcessToGcListLocked(rec);
4662                }
4663            }
4664            if (doReport) {
4665                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4666                mHandler.sendMessage(msg);
4667            }
4668            scheduleAppGcsLocked();
4669        }
4670    }
4671
4672    final void appDiedLocked(ProcessRecord app) {
4673       appDiedLocked(app, app.pid, app.thread);
4674    }
4675
4676    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4677        // First check if this ProcessRecord is actually active for the pid.
4678        synchronized (mPidsSelfLocked) {
4679            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4680            if (curProc != app) {
4681                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4682                return;
4683            }
4684        }
4685
4686        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4687        synchronized (stats) {
4688            stats.noteProcessDiedLocked(app.info.uid, pid);
4689        }
4690
4691        if (!app.killed) {
4692            Process.killProcessQuiet(pid);
4693            Process.killProcessGroup(app.info.uid, pid);
4694            app.killed = true;
4695        }
4696
4697        // Clean up already done if the process has been re-started.
4698        if (app.pid == pid && app.thread != null &&
4699                app.thread.asBinder() == thread.asBinder()) {
4700            boolean doLowMem = app.instrumentationClass == null;
4701            boolean doOomAdj = doLowMem;
4702            if (!app.killedByAm) {
4703                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4704                        + ") has died");
4705                mAllowLowerMemLevel = true;
4706            } else {
4707                // Note that we always want to do oom adj to update our state with the
4708                // new number of procs.
4709                mAllowLowerMemLevel = false;
4710                doLowMem = false;
4711            }
4712            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4713            if (DEBUG_CLEANUP) Slog.v(
4714                TAG, "Dying app: " + app + ", pid: " + pid
4715                + ", thread: " + thread.asBinder());
4716            handleAppDiedLocked(app, false, true);
4717
4718            if (doOomAdj) {
4719                updateOomAdjLocked();
4720            }
4721            if (doLowMem) {
4722                doLowMemReportIfNeededLocked(app);
4723            }
4724        } else if (app.pid != pid) {
4725            // A new process has already been started.
4726            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727                    + ") has died and restarted (pid " + app.pid + ").");
4728            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4729        } else if (DEBUG_PROCESSES) {
4730            Slog.d(TAG, "Received spurious death notification for thread "
4731                    + thread.asBinder());
4732        }
4733    }
4734
4735    /**
4736     * If a stack trace dump file is configured, dump process stack traces.
4737     * @param clearTraces causes the dump file to be erased prior to the new
4738     *    traces being written, if true; when false, the new traces will be
4739     *    appended to any existing file content.
4740     * @param firstPids of dalvik VM processes to dump stack traces for first
4741     * @param lastPids of dalvik VM processes to dump stack traces for last
4742     * @param nativeProcs optional list of native process names to dump stack crawls
4743     * @return file containing stack traces, or null if no dump file is configured
4744     */
4745    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4746            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4747        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4748        if (tracesPath == null || tracesPath.length() == 0) {
4749            return null;
4750        }
4751
4752        File tracesFile = new File(tracesPath);
4753        try {
4754            File tracesDir = tracesFile.getParentFile();
4755            if (!tracesDir.exists()) {
4756                tracesDir.mkdirs();
4757                if (!SELinux.restorecon(tracesDir)) {
4758                    return null;
4759                }
4760            }
4761            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4762
4763            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4764            tracesFile.createNewFile();
4765            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4766        } catch (IOException e) {
4767            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4768            return null;
4769        }
4770
4771        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4772        return tracesFile;
4773    }
4774
4775    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4776            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4777        // Use a FileObserver to detect when traces finish writing.
4778        // The order of traces is considered important to maintain for legibility.
4779        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4780            @Override
4781            public synchronized void onEvent(int event, String path) { notify(); }
4782        };
4783
4784        try {
4785            observer.startWatching();
4786
4787            // First collect all of the stacks of the most important pids.
4788            if (firstPids != null) {
4789                try {
4790                    int num = firstPids.size();
4791                    for (int i = 0; i < num; i++) {
4792                        synchronized (observer) {
4793                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4794                            observer.wait(200);  // Wait for write-close, give up after 200msec
4795                        }
4796                    }
4797                } catch (InterruptedException e) {
4798                    Slog.wtf(TAG, e);
4799                }
4800            }
4801
4802            // Next collect the stacks of the native pids
4803            if (nativeProcs != null) {
4804                int[] pids = Process.getPidsForCommands(nativeProcs);
4805                if (pids != null) {
4806                    for (int pid : pids) {
4807                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4808                    }
4809                }
4810            }
4811
4812            // Lastly, measure CPU usage.
4813            if (processCpuTracker != null) {
4814                processCpuTracker.init();
4815                System.gc();
4816                processCpuTracker.update();
4817                try {
4818                    synchronized (processCpuTracker) {
4819                        processCpuTracker.wait(500); // measure over 1/2 second.
4820                    }
4821                } catch (InterruptedException e) {
4822                }
4823                processCpuTracker.update();
4824
4825                // We'll take the stack crawls of just the top apps using CPU.
4826                final int N = processCpuTracker.countWorkingStats();
4827                int numProcs = 0;
4828                for (int i=0; i<N && numProcs<5; i++) {
4829                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4830                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4831                        numProcs++;
4832                        try {
4833                            synchronized (observer) {
4834                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4835                                observer.wait(200);  // Wait for write-close, give up after 200msec
4836                            }
4837                        } catch (InterruptedException e) {
4838                            Slog.wtf(TAG, e);
4839                        }
4840
4841                    }
4842                }
4843            }
4844        } finally {
4845            observer.stopWatching();
4846        }
4847    }
4848
4849    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4850        if (true || IS_USER_BUILD) {
4851            return;
4852        }
4853        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4854        if (tracesPath == null || tracesPath.length() == 0) {
4855            return;
4856        }
4857
4858        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4859        StrictMode.allowThreadDiskWrites();
4860        try {
4861            final File tracesFile = new File(tracesPath);
4862            final File tracesDir = tracesFile.getParentFile();
4863            final File tracesTmp = new File(tracesDir, "__tmp__");
4864            try {
4865                if (!tracesDir.exists()) {
4866                    tracesDir.mkdirs();
4867                    if (!SELinux.restorecon(tracesDir.getPath())) {
4868                        return;
4869                    }
4870                }
4871                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4872
4873                if (tracesFile.exists()) {
4874                    tracesTmp.delete();
4875                    tracesFile.renameTo(tracesTmp);
4876                }
4877                StringBuilder sb = new StringBuilder();
4878                Time tobj = new Time();
4879                tobj.set(System.currentTimeMillis());
4880                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4881                sb.append(": ");
4882                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4883                sb.append(" since ");
4884                sb.append(msg);
4885                FileOutputStream fos = new FileOutputStream(tracesFile);
4886                fos.write(sb.toString().getBytes());
4887                if (app == null) {
4888                    fos.write("\n*** No application process!".getBytes());
4889                }
4890                fos.close();
4891                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4892            } catch (IOException e) {
4893                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4894                return;
4895            }
4896
4897            if (app != null) {
4898                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4899                firstPids.add(app.pid);
4900                dumpStackTraces(tracesPath, firstPids, null, null, null);
4901            }
4902
4903            File lastTracesFile = null;
4904            File curTracesFile = null;
4905            for (int i=9; i>=0; i--) {
4906                String name = String.format(Locale.US, "slow%02d.txt", i);
4907                curTracesFile = new File(tracesDir, name);
4908                if (curTracesFile.exists()) {
4909                    if (lastTracesFile != null) {
4910                        curTracesFile.renameTo(lastTracesFile);
4911                    } else {
4912                        curTracesFile.delete();
4913                    }
4914                }
4915                lastTracesFile = curTracesFile;
4916            }
4917            tracesFile.renameTo(curTracesFile);
4918            if (tracesTmp.exists()) {
4919                tracesTmp.renameTo(tracesFile);
4920            }
4921        } finally {
4922            StrictMode.setThreadPolicy(oldPolicy);
4923        }
4924    }
4925
4926    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4927            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4928        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4929        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4930
4931        if (mController != null) {
4932            try {
4933                // 0 == continue, -1 = kill process immediately
4934                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4935                if (res < 0 && app.pid != MY_PID) {
4936                    app.kill("anr", true);
4937                }
4938            } catch (RemoteException e) {
4939                mController = null;
4940                Watchdog.getInstance().setActivityController(null);
4941            }
4942        }
4943
4944        long anrTime = SystemClock.uptimeMillis();
4945        if (MONITOR_CPU_USAGE) {
4946            updateCpuStatsNow();
4947        }
4948
4949        synchronized (this) {
4950            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4951            if (mShuttingDown) {
4952                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4953                return;
4954            } else if (app.notResponding) {
4955                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4956                return;
4957            } else if (app.crashing) {
4958                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4959                return;
4960            }
4961
4962            // In case we come through here for the same app before completing
4963            // this one, mark as anring now so we will bail out.
4964            app.notResponding = true;
4965
4966            // Log the ANR to the event log.
4967            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4968                    app.processName, app.info.flags, annotation);
4969
4970            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4971            firstPids.add(app.pid);
4972
4973            int parentPid = app.pid;
4974            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4975            if (parentPid != app.pid) firstPids.add(parentPid);
4976
4977            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4978
4979            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4980                ProcessRecord r = mLruProcesses.get(i);
4981                if (r != null && r.thread != null) {
4982                    int pid = r.pid;
4983                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4984                        if (r.persistent) {
4985                            firstPids.add(pid);
4986                        } else {
4987                            lastPids.put(pid, Boolean.TRUE);
4988                        }
4989                    }
4990                }
4991            }
4992        }
4993
4994        // Log the ANR to the main log.
4995        StringBuilder info = new StringBuilder();
4996        info.setLength(0);
4997        info.append("ANR in ").append(app.processName);
4998        if (activity != null && activity.shortComponentName != null) {
4999            info.append(" (").append(activity.shortComponentName).append(")");
5000        }
5001        info.append("\n");
5002        info.append("PID: ").append(app.pid).append("\n");
5003        if (annotation != null) {
5004            info.append("Reason: ").append(annotation).append("\n");
5005        }
5006        if (parent != null && parent != activity) {
5007            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5008        }
5009
5010        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5011
5012        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5013                NATIVE_STACKS_OF_INTEREST);
5014
5015        String cpuInfo = null;
5016        if (MONITOR_CPU_USAGE) {
5017            updateCpuStatsNow();
5018            synchronized (mProcessCpuTracker) {
5019                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5020            }
5021            info.append(processCpuTracker.printCurrentLoad());
5022            info.append(cpuInfo);
5023        }
5024
5025        info.append(processCpuTracker.printCurrentState(anrTime));
5026
5027        Slog.e(TAG, info.toString());
5028        if (tracesFile == null) {
5029            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5030            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5031        }
5032
5033        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5034                cpuInfo, tracesFile, null);
5035
5036        if (mController != null) {
5037            try {
5038                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5039                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5040                if (res != 0) {
5041                    if (res < 0 && app.pid != MY_PID) {
5042                        app.kill("anr", true);
5043                    } else {
5044                        synchronized (this) {
5045                            mServices.scheduleServiceTimeoutLocked(app);
5046                        }
5047                    }
5048                    return;
5049                }
5050            } catch (RemoteException e) {
5051                mController = null;
5052                Watchdog.getInstance().setActivityController(null);
5053            }
5054        }
5055
5056        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5057        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5058                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5059
5060        synchronized (this) {
5061            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5062
5063            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5064                app.kill("bg anr", true);
5065                return;
5066            }
5067
5068            // Set the app's notResponding state, and look up the errorReportReceiver
5069            makeAppNotRespondingLocked(app,
5070                    activity != null ? activity.shortComponentName : null,
5071                    annotation != null ? "ANR " + annotation : "ANR",
5072                    info.toString());
5073
5074            // Bring up the infamous App Not Responding dialog
5075            Message msg = Message.obtain();
5076            HashMap<String, Object> map = new HashMap<String, Object>();
5077            msg.what = SHOW_NOT_RESPONDING_MSG;
5078            msg.obj = map;
5079            msg.arg1 = aboveSystem ? 1 : 0;
5080            map.put("app", app);
5081            if (activity != null) {
5082                map.put("activity", activity);
5083            }
5084
5085            mHandler.sendMessage(msg);
5086        }
5087    }
5088
5089    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5090        if (!mLaunchWarningShown) {
5091            mLaunchWarningShown = true;
5092            mHandler.post(new Runnable() {
5093                @Override
5094                public void run() {
5095                    synchronized (ActivityManagerService.this) {
5096                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5097                        d.show();
5098                        mHandler.postDelayed(new Runnable() {
5099                            @Override
5100                            public void run() {
5101                                synchronized (ActivityManagerService.this) {
5102                                    d.dismiss();
5103                                    mLaunchWarningShown = false;
5104                                }
5105                            }
5106                        }, 4000);
5107                    }
5108                }
5109            });
5110        }
5111    }
5112
5113    @Override
5114    public boolean clearApplicationUserData(final String packageName,
5115            final IPackageDataObserver observer, int userId) {
5116        enforceNotIsolatedCaller("clearApplicationUserData");
5117        int uid = Binder.getCallingUid();
5118        int pid = Binder.getCallingPid();
5119        userId = handleIncomingUser(pid, uid,
5120                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5121        long callingId = Binder.clearCallingIdentity();
5122        try {
5123            IPackageManager pm = AppGlobals.getPackageManager();
5124            int pkgUid = -1;
5125            synchronized(this) {
5126                try {
5127                    pkgUid = pm.getPackageUid(packageName, userId);
5128                } catch (RemoteException e) {
5129                }
5130                if (pkgUid == -1) {
5131                    Slog.w(TAG, "Invalid packageName: " + packageName);
5132                    if (observer != null) {
5133                        try {
5134                            observer.onRemoveCompleted(packageName, false);
5135                        } catch (RemoteException e) {
5136                            Slog.i(TAG, "Observer no longer exists.");
5137                        }
5138                    }
5139                    return false;
5140                }
5141                if (uid == pkgUid || checkComponentPermission(
5142                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5143                        pid, uid, -1, true)
5144                        == PackageManager.PERMISSION_GRANTED) {
5145                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5146                } else {
5147                    throw new SecurityException("PID " + pid + " does not have permission "
5148                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5149                                    + " of package " + packageName);
5150                }
5151
5152                // Remove all tasks match the cleared application package and user
5153                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5154                    final TaskRecord tr = mRecentTasks.get(i);
5155                    final String taskPackageName =
5156                            tr.getBaseIntent().getComponent().getPackageName();
5157                    if (tr.userId != userId) continue;
5158                    if (!taskPackageName.equals(packageName)) continue;
5159                    removeTaskByIdLocked(tr.taskId, false);
5160                }
5161            }
5162
5163            try {
5164                // Clear application user data
5165                pm.clearApplicationUserData(packageName, observer, userId);
5166
5167                synchronized(this) {
5168                    // Remove all permissions granted from/to this package
5169                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5170                }
5171
5172                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5173                        Uri.fromParts("package", packageName, null));
5174                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5175                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5176                        null, null, 0, null, null, null, false, false, userId);
5177            } catch (RemoteException e) {
5178            }
5179        } finally {
5180            Binder.restoreCallingIdentity(callingId);
5181        }
5182        return true;
5183    }
5184
5185    @Override
5186    public void killBackgroundProcesses(final String packageName, int userId) {
5187        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5188                != PackageManager.PERMISSION_GRANTED &&
5189                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5190                        != PackageManager.PERMISSION_GRANTED) {
5191            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5192                    + Binder.getCallingPid()
5193                    + ", uid=" + Binder.getCallingUid()
5194                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5195            Slog.w(TAG, msg);
5196            throw new SecurityException(msg);
5197        }
5198
5199        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5200                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            IPackageManager pm = AppGlobals.getPackageManager();
5204            synchronized(this) {
5205                int appId = -1;
5206                try {
5207                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5208                } catch (RemoteException e) {
5209                }
5210                if (appId == -1) {
5211                    Slog.w(TAG, "Invalid packageName: " + packageName);
5212                    return;
5213                }
5214                killPackageProcessesLocked(packageName, appId, userId,
5215                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5216            }
5217        } finally {
5218            Binder.restoreCallingIdentity(callingId);
5219        }
5220    }
5221
5222    @Override
5223    public void killAllBackgroundProcesses() {
5224        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5225                != PackageManager.PERMISSION_GRANTED) {
5226            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5227                    + Binder.getCallingPid()
5228                    + ", uid=" + Binder.getCallingUid()
5229                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5230            Slog.w(TAG, msg);
5231            throw new SecurityException(msg);
5232        }
5233
5234        long callingId = Binder.clearCallingIdentity();
5235        try {
5236            synchronized(this) {
5237                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5238                final int NP = mProcessNames.getMap().size();
5239                for (int ip=0; ip<NP; ip++) {
5240                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5241                    final int NA = apps.size();
5242                    for (int ia=0; ia<NA; ia++) {
5243                        ProcessRecord app = apps.valueAt(ia);
5244                        if (app.persistent) {
5245                            // we don't kill persistent processes
5246                            continue;
5247                        }
5248                        if (app.removed) {
5249                            procs.add(app);
5250                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5251                            app.removed = true;
5252                            procs.add(app);
5253                        }
5254                    }
5255                }
5256
5257                int N = procs.size();
5258                for (int i=0; i<N; i++) {
5259                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5260                }
5261                mAllowLowerMemLevel = true;
5262                updateOomAdjLocked();
5263                doLowMemReportIfNeededLocked(null);
5264            }
5265        } finally {
5266            Binder.restoreCallingIdentity(callingId);
5267        }
5268    }
5269
5270    @Override
5271    public void forceStopPackage(final String packageName, int userId) {
5272        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5273                != PackageManager.PERMISSION_GRANTED) {
5274            String msg = "Permission Denial: forceStopPackage() from pid="
5275                    + Binder.getCallingPid()
5276                    + ", uid=" + Binder.getCallingUid()
5277                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5278            Slog.w(TAG, msg);
5279            throw new SecurityException(msg);
5280        }
5281        final int callingPid = Binder.getCallingPid();
5282        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5283                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5284        long callingId = Binder.clearCallingIdentity();
5285        try {
5286            IPackageManager pm = AppGlobals.getPackageManager();
5287            synchronized(this) {
5288                int[] users = userId == UserHandle.USER_ALL
5289                        ? getUsersLocked() : new int[] { userId };
5290                for (int user : users) {
5291                    int pkgUid = -1;
5292                    try {
5293                        pkgUid = pm.getPackageUid(packageName, user);
5294                    } catch (RemoteException e) {
5295                    }
5296                    if (pkgUid == -1) {
5297                        Slog.w(TAG, "Invalid packageName: " + packageName);
5298                        continue;
5299                    }
5300                    try {
5301                        pm.setPackageStoppedState(packageName, true, user);
5302                    } catch (RemoteException e) {
5303                    } catch (IllegalArgumentException e) {
5304                        Slog.w(TAG, "Failed trying to unstop package "
5305                                + packageName + ": " + e);
5306                    }
5307                    if (isUserRunningLocked(user, false)) {
5308                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5309                    }
5310                }
5311            }
5312        } finally {
5313            Binder.restoreCallingIdentity(callingId);
5314        }
5315    }
5316
5317    @Override
5318    public void addPackageDependency(String packageName) {
5319        synchronized (this) {
5320            int callingPid = Binder.getCallingPid();
5321            if (callingPid == Process.myPid()) {
5322                //  Yeah, um, no.
5323                return;
5324            }
5325            ProcessRecord proc;
5326            synchronized (mPidsSelfLocked) {
5327                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5328            }
5329            if (proc != null) {
5330                if (proc.pkgDeps == null) {
5331                    proc.pkgDeps = new ArraySet<String>(1);
5332                }
5333                proc.pkgDeps.add(packageName);
5334            }
5335        }
5336    }
5337
5338    /*
5339     * The pkg name and app id have to be specified.
5340     */
5341    @Override
5342    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5343        if (pkg == null) {
5344            return;
5345        }
5346        // Make sure the uid is valid.
5347        if (appid < 0) {
5348            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5349            return;
5350        }
5351        int callerUid = Binder.getCallingUid();
5352        // Only the system server can kill an application
5353        if (callerUid == Process.SYSTEM_UID) {
5354            // Post an aysnc message to kill the application
5355            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5356            msg.arg1 = appid;
5357            msg.arg2 = 0;
5358            Bundle bundle = new Bundle();
5359            bundle.putString("pkg", pkg);
5360            bundle.putString("reason", reason);
5361            msg.obj = bundle;
5362            mHandler.sendMessage(msg);
5363        } else {
5364            throw new SecurityException(callerUid + " cannot kill pkg: " +
5365                    pkg);
5366        }
5367    }
5368
5369    @Override
5370    public void closeSystemDialogs(String reason) {
5371        enforceNotIsolatedCaller("closeSystemDialogs");
5372
5373        final int pid = Binder.getCallingPid();
5374        final int uid = Binder.getCallingUid();
5375        final long origId = Binder.clearCallingIdentity();
5376        try {
5377            synchronized (this) {
5378                // Only allow this from foreground processes, so that background
5379                // applications can't abuse it to prevent system UI from being shown.
5380                if (uid >= Process.FIRST_APPLICATION_UID) {
5381                    ProcessRecord proc;
5382                    synchronized (mPidsSelfLocked) {
5383                        proc = mPidsSelfLocked.get(pid);
5384                    }
5385                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5386                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5387                                + " from background process " + proc);
5388                        return;
5389                    }
5390                }
5391                closeSystemDialogsLocked(reason);
5392            }
5393        } finally {
5394            Binder.restoreCallingIdentity(origId);
5395        }
5396    }
5397
5398    void closeSystemDialogsLocked(String reason) {
5399        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5400        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5401                | Intent.FLAG_RECEIVER_FOREGROUND);
5402        if (reason != null) {
5403            intent.putExtra("reason", reason);
5404        }
5405        mWindowManager.closeSystemDialogs(reason);
5406
5407        mStackSupervisor.closeSystemDialogsLocked();
5408
5409        broadcastIntentLocked(null, null, intent, null,
5410                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5411                Process.SYSTEM_UID, UserHandle.USER_ALL);
5412    }
5413
5414    @Override
5415    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5416        enforceNotIsolatedCaller("getProcessMemoryInfo");
5417        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5418        for (int i=pids.length-1; i>=0; i--) {
5419            ProcessRecord proc;
5420            int oomAdj;
5421            synchronized (this) {
5422                synchronized (mPidsSelfLocked) {
5423                    proc = mPidsSelfLocked.get(pids[i]);
5424                    oomAdj = proc != null ? proc.setAdj : 0;
5425                }
5426            }
5427            infos[i] = new Debug.MemoryInfo();
5428            Debug.getMemoryInfo(pids[i], infos[i]);
5429            if (proc != null) {
5430                synchronized (this) {
5431                    if (proc.thread != null && proc.setAdj == oomAdj) {
5432                        // Record this for posterity if the process has been stable.
5433                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5434                                infos[i].getTotalUss(), false, proc.pkgList);
5435                    }
5436                }
5437            }
5438        }
5439        return infos;
5440    }
5441
5442    @Override
5443    public long[] getProcessPss(int[] pids) {
5444        enforceNotIsolatedCaller("getProcessPss");
5445        long[] pss = new long[pids.length];
5446        for (int i=pids.length-1; i>=0; i--) {
5447            ProcessRecord proc;
5448            int oomAdj;
5449            synchronized (this) {
5450                synchronized (mPidsSelfLocked) {
5451                    proc = mPidsSelfLocked.get(pids[i]);
5452                    oomAdj = proc != null ? proc.setAdj : 0;
5453                }
5454            }
5455            long[] tmpUss = new long[1];
5456            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5457            if (proc != null) {
5458                synchronized (this) {
5459                    if (proc.thread != null && proc.setAdj == oomAdj) {
5460                        // Record this for posterity if the process has been stable.
5461                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5462                    }
5463                }
5464            }
5465        }
5466        return pss;
5467    }
5468
5469    @Override
5470    public void killApplicationProcess(String processName, int uid) {
5471        if (processName == null) {
5472            return;
5473        }
5474
5475        int callerUid = Binder.getCallingUid();
5476        // Only the system server can kill an application
5477        if (callerUid == Process.SYSTEM_UID) {
5478            synchronized (this) {
5479                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5480                if (app != null && app.thread != null) {
5481                    try {
5482                        app.thread.scheduleSuicide();
5483                    } catch (RemoteException e) {
5484                        // If the other end already died, then our work here is done.
5485                    }
5486                } else {
5487                    Slog.w(TAG, "Process/uid not found attempting kill of "
5488                            + processName + " / " + uid);
5489                }
5490            }
5491        } else {
5492            throw new SecurityException(callerUid + " cannot kill app process: " +
5493                    processName);
5494        }
5495    }
5496
5497    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5498        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5499                false, true, false, false, UserHandle.getUserId(uid), reason);
5500        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5501                Uri.fromParts("package", packageName, null));
5502        if (!mProcessesReady) {
5503            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5504                    | Intent.FLAG_RECEIVER_FOREGROUND);
5505        }
5506        intent.putExtra(Intent.EXTRA_UID, uid);
5507        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5508        broadcastIntentLocked(null, null, intent,
5509                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5510                false, false,
5511                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5512    }
5513
5514    private void forceStopUserLocked(int userId, String reason) {
5515        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5516        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5517        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5518                | Intent.FLAG_RECEIVER_FOREGROUND);
5519        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5520        broadcastIntentLocked(null, null, intent,
5521                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5522                false, false,
5523                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5524    }
5525
5526    private final boolean killPackageProcessesLocked(String packageName, int appId,
5527            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5528            boolean doit, boolean evenPersistent, String reason) {
5529        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5530
5531        // Remove all processes this package may have touched: all with the
5532        // same UID (except for the system or root user), and all whose name
5533        // matches the package name.
5534        final int NP = mProcessNames.getMap().size();
5535        for (int ip=0; ip<NP; ip++) {
5536            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5537            final int NA = apps.size();
5538            for (int ia=0; ia<NA; ia++) {
5539                ProcessRecord app = apps.valueAt(ia);
5540                if (app.persistent && !evenPersistent) {
5541                    // we don't kill persistent processes
5542                    continue;
5543                }
5544                if (app.removed) {
5545                    if (doit) {
5546                        procs.add(app);
5547                    }
5548                    continue;
5549                }
5550
5551                // Skip process if it doesn't meet our oom adj requirement.
5552                if (app.setAdj < minOomAdj) {
5553                    continue;
5554                }
5555
5556                // If no package is specified, we call all processes under the
5557                // give user id.
5558                if (packageName == null) {
5559                    if (app.userId != userId) {
5560                        continue;
5561                    }
5562                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5563                        continue;
5564                    }
5565                // Package has been specified, we want to hit all processes
5566                // that match it.  We need to qualify this by the processes
5567                // that are running under the specified app and user ID.
5568                } else {
5569                    final boolean isDep = app.pkgDeps != null
5570                            && app.pkgDeps.contains(packageName);
5571                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5572                        continue;
5573                    }
5574                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5575                        continue;
5576                    }
5577                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5578                        continue;
5579                    }
5580                }
5581
5582                // Process has passed all conditions, kill it!
5583                if (!doit) {
5584                    return true;
5585                }
5586                app.removed = true;
5587                procs.add(app);
5588            }
5589        }
5590
5591        int N = procs.size();
5592        for (int i=0; i<N; i++) {
5593            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5594        }
5595        updateOomAdjLocked();
5596        return N > 0;
5597    }
5598
5599    private final boolean forceStopPackageLocked(String name, int appId,
5600            boolean callerWillRestart, boolean purgeCache, boolean doit,
5601            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5602        int i;
5603        int N;
5604
5605        if (userId == UserHandle.USER_ALL && name == null) {
5606            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5607        }
5608
5609        if (appId < 0 && name != null) {
5610            try {
5611                appId = UserHandle.getAppId(
5612                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5613            } catch (RemoteException e) {
5614            }
5615        }
5616
5617        if (doit) {
5618            if (name != null) {
5619                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5620                        + " user=" + userId + ": " + reason);
5621            } else {
5622                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5623            }
5624
5625            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5626            for (int ip=pmap.size()-1; ip>=0; ip--) {
5627                SparseArray<Long> ba = pmap.valueAt(ip);
5628                for (i=ba.size()-1; i>=0; i--) {
5629                    boolean remove = false;
5630                    final int entUid = ba.keyAt(i);
5631                    if (name != null) {
5632                        if (userId == UserHandle.USER_ALL) {
5633                            if (UserHandle.getAppId(entUid) == appId) {
5634                                remove = true;
5635                            }
5636                        } else {
5637                            if (entUid == UserHandle.getUid(userId, appId)) {
5638                                remove = true;
5639                            }
5640                        }
5641                    } else if (UserHandle.getUserId(entUid) == userId) {
5642                        remove = true;
5643                    }
5644                    if (remove) {
5645                        ba.removeAt(i);
5646                    }
5647                }
5648                if (ba.size() == 0) {
5649                    pmap.removeAt(ip);
5650                }
5651            }
5652        }
5653
5654        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5655                -100, callerWillRestart, true, doit, evenPersistent,
5656                name == null ? ("stop user " + userId) : ("stop " + name));
5657
5658        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5659            if (!doit) {
5660                return true;
5661            }
5662            didSomething = true;
5663        }
5664
5665        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5666            if (!doit) {
5667                return true;
5668            }
5669            didSomething = true;
5670        }
5671
5672        if (name == null) {
5673            // Remove all sticky broadcasts from this user.
5674            mStickyBroadcasts.remove(userId);
5675        }
5676
5677        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5678        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5679                userId, providers)) {
5680            if (!doit) {
5681                return true;
5682            }
5683            didSomething = true;
5684        }
5685        N = providers.size();
5686        for (i=0; i<N; i++) {
5687            removeDyingProviderLocked(null, providers.get(i), true);
5688        }
5689
5690        // Remove transient permissions granted from/to this package/user
5691        removeUriPermissionsForPackageLocked(name, userId, false);
5692
5693        if (name == null || uninstalling) {
5694            // Remove pending intents.  For now we only do this when force
5695            // stopping users, because we have some problems when doing this
5696            // for packages -- app widgets are not currently cleaned up for
5697            // such packages, so they can be left with bad pending intents.
5698            if (mIntentSenderRecords.size() > 0) {
5699                Iterator<WeakReference<PendingIntentRecord>> it
5700                        = mIntentSenderRecords.values().iterator();
5701                while (it.hasNext()) {
5702                    WeakReference<PendingIntentRecord> wpir = it.next();
5703                    if (wpir == null) {
5704                        it.remove();
5705                        continue;
5706                    }
5707                    PendingIntentRecord pir = wpir.get();
5708                    if (pir == null) {
5709                        it.remove();
5710                        continue;
5711                    }
5712                    if (name == null) {
5713                        // Stopping user, remove all objects for the user.
5714                        if (pir.key.userId != userId) {
5715                            // Not the same user, skip it.
5716                            continue;
5717                        }
5718                    } else {
5719                        if (UserHandle.getAppId(pir.uid) != appId) {
5720                            // Different app id, skip it.
5721                            continue;
5722                        }
5723                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5724                            // Different user, skip it.
5725                            continue;
5726                        }
5727                        if (!pir.key.packageName.equals(name)) {
5728                            // Different package, skip it.
5729                            continue;
5730                        }
5731                    }
5732                    if (!doit) {
5733                        return true;
5734                    }
5735                    didSomething = true;
5736                    it.remove();
5737                    pir.canceled = true;
5738                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5739                        pir.key.activity.pendingResults.remove(pir.ref);
5740                    }
5741                }
5742            }
5743        }
5744
5745        if (doit) {
5746            if (purgeCache && name != null) {
5747                AttributeCache ac = AttributeCache.instance();
5748                if (ac != null) {
5749                    ac.removePackage(name);
5750                }
5751            }
5752            if (mBooted) {
5753                mStackSupervisor.resumeTopActivitiesLocked();
5754                mStackSupervisor.scheduleIdleLocked();
5755            }
5756        }
5757
5758        return didSomething;
5759    }
5760
5761    private final boolean removeProcessLocked(ProcessRecord app,
5762            boolean callerWillRestart, boolean allowRestart, String reason) {
5763        final String name = app.processName;
5764        final int uid = app.uid;
5765        if (DEBUG_PROCESSES) Slog.d(
5766            TAG, "Force removing proc " + app.toShortString() + " (" + name
5767            + "/" + uid + ")");
5768
5769        mProcessNames.remove(name, uid);
5770        mIsolatedProcesses.remove(app.uid);
5771        if (mHeavyWeightProcess == app) {
5772            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5773                    mHeavyWeightProcess.userId, 0));
5774            mHeavyWeightProcess = null;
5775        }
5776        boolean needRestart = false;
5777        if (app.pid > 0 && app.pid != MY_PID) {
5778            int pid = app.pid;
5779            synchronized (mPidsSelfLocked) {
5780                mPidsSelfLocked.remove(pid);
5781                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5782            }
5783            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5784            if (app.isolated) {
5785                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5786            }
5787            app.kill(reason, true);
5788            handleAppDiedLocked(app, true, allowRestart);
5789            removeLruProcessLocked(app);
5790
5791            if (app.persistent && !app.isolated) {
5792                if (!callerWillRestart) {
5793                    addAppLocked(app.info, false, null /* ABI override */);
5794                } else {
5795                    needRestart = true;
5796                }
5797            }
5798        } else {
5799            mRemovedProcesses.add(app);
5800        }
5801
5802        return needRestart;
5803    }
5804
5805    private final void processStartTimedOutLocked(ProcessRecord app) {
5806        final int pid = app.pid;
5807        boolean gone = false;
5808        synchronized (mPidsSelfLocked) {
5809            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5810            if (knownApp != null && knownApp.thread == null) {
5811                mPidsSelfLocked.remove(pid);
5812                gone = true;
5813            }
5814        }
5815
5816        if (gone) {
5817            Slog.w(TAG, "Process " + app + " failed to attach");
5818            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5819                    pid, app.uid, app.processName);
5820            mProcessNames.remove(app.processName, app.uid);
5821            mIsolatedProcesses.remove(app.uid);
5822            if (mHeavyWeightProcess == app) {
5823                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5824                        mHeavyWeightProcess.userId, 0));
5825                mHeavyWeightProcess = null;
5826            }
5827            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5828            if (app.isolated) {
5829                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5830            }
5831            // Take care of any launching providers waiting for this process.
5832            checkAppInLaunchingProvidersLocked(app, true);
5833            // Take care of any services that are waiting for the process.
5834            mServices.processStartTimedOutLocked(app);
5835            app.kill("start timeout", true);
5836            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5837                Slog.w(TAG, "Unattached app died before backup, skipping");
5838                try {
5839                    IBackupManager bm = IBackupManager.Stub.asInterface(
5840                            ServiceManager.getService(Context.BACKUP_SERVICE));
5841                    bm.agentDisconnected(app.info.packageName);
5842                } catch (RemoteException e) {
5843                    // Can't happen; the backup manager is local
5844                }
5845            }
5846            if (isPendingBroadcastProcessLocked(pid)) {
5847                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5848                skipPendingBroadcastLocked(pid);
5849            }
5850        } else {
5851            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5852        }
5853    }
5854
5855    private final boolean attachApplicationLocked(IApplicationThread thread,
5856            int pid) {
5857
5858        // Find the application record that is being attached...  either via
5859        // the pid if we are running in multiple processes, or just pull the
5860        // next app record if we are emulating process with anonymous threads.
5861        ProcessRecord app;
5862        if (pid != MY_PID && pid >= 0) {
5863            synchronized (mPidsSelfLocked) {
5864                app = mPidsSelfLocked.get(pid);
5865            }
5866        } else {
5867            app = null;
5868        }
5869
5870        if (app == null) {
5871            Slog.w(TAG, "No pending application record for pid " + pid
5872                    + " (IApplicationThread " + thread + "); dropping process");
5873            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5874            if (pid > 0 && pid != MY_PID) {
5875                Process.killProcessQuiet(pid);
5876                //TODO: Process.killProcessGroup(app.info.uid, pid);
5877            } else {
5878                try {
5879                    thread.scheduleExit();
5880                } catch (Exception e) {
5881                    // Ignore exceptions.
5882                }
5883            }
5884            return false;
5885        }
5886
5887        // If this application record is still attached to a previous
5888        // process, clean it up now.
5889        if (app.thread != null) {
5890            handleAppDiedLocked(app, true, true);
5891        }
5892
5893        // Tell the process all about itself.
5894
5895        if (localLOGV) Slog.v(
5896                TAG, "Binding process pid " + pid + " to record " + app);
5897
5898        final String processName = app.processName;
5899        try {
5900            AppDeathRecipient adr = new AppDeathRecipient(
5901                    app, pid, thread);
5902            thread.asBinder().linkToDeath(adr, 0);
5903            app.deathRecipient = adr;
5904        } catch (RemoteException e) {
5905            app.resetPackageList(mProcessStats);
5906            startProcessLocked(app, "link fail", processName);
5907            return false;
5908        }
5909
5910        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5911
5912        app.makeActive(thread, mProcessStats);
5913        app.curAdj = app.setAdj = -100;
5914        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5915        app.forcingToForeground = null;
5916        updateProcessForegroundLocked(app, false, false);
5917        app.hasShownUi = false;
5918        app.debugging = false;
5919        app.cached = false;
5920        app.killedByAm = false;
5921
5922        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5923
5924        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5925        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5926
5927        if (!normalMode) {
5928            Slog.i(TAG, "Launching preboot mode app: " + app);
5929        }
5930
5931        if (localLOGV) Slog.v(
5932            TAG, "New app record " + app
5933            + " thread=" + thread.asBinder() + " pid=" + pid);
5934        try {
5935            int testMode = IApplicationThread.DEBUG_OFF;
5936            if (mDebugApp != null && mDebugApp.equals(processName)) {
5937                testMode = mWaitForDebugger
5938                    ? IApplicationThread.DEBUG_WAIT
5939                    : IApplicationThread.DEBUG_ON;
5940                app.debugging = true;
5941                if (mDebugTransient) {
5942                    mDebugApp = mOrigDebugApp;
5943                    mWaitForDebugger = mOrigWaitForDebugger;
5944                }
5945            }
5946            String profileFile = app.instrumentationProfileFile;
5947            ParcelFileDescriptor profileFd = null;
5948            int samplingInterval = 0;
5949            boolean profileAutoStop = false;
5950            if (mProfileApp != null && mProfileApp.equals(processName)) {
5951                mProfileProc = app;
5952                profileFile = mProfileFile;
5953                profileFd = mProfileFd;
5954                samplingInterval = mSamplingInterval;
5955                profileAutoStop = mAutoStopProfiler;
5956            }
5957            boolean enableOpenGlTrace = false;
5958            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5959                enableOpenGlTrace = true;
5960                mOpenGlTraceApp = null;
5961            }
5962
5963            // If the app is being launched for restore or full backup, set it up specially
5964            boolean isRestrictedBackupMode = false;
5965            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5966                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5967                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5968                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5969            }
5970
5971            ensurePackageDexOpt(app.instrumentationInfo != null
5972                    ? app.instrumentationInfo.packageName
5973                    : app.info.packageName);
5974            if (app.instrumentationClass != null) {
5975                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5976            }
5977            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5978                    + processName + " with config " + mConfiguration);
5979            ApplicationInfo appInfo = app.instrumentationInfo != null
5980                    ? app.instrumentationInfo : app.info;
5981            app.compat = compatibilityInfoForPackageLocked(appInfo);
5982            if (profileFd != null) {
5983                profileFd = profileFd.dup();
5984            }
5985            ProfilerInfo profilerInfo = profileFile == null ? null
5986                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5987            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5988                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5989                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5990                    isRestrictedBackupMode || !normalMode, app.persistent,
5991                    new Configuration(mConfiguration), app.compat,
5992                    getCommonServicesLocked(app.isolated),
5993                    mCoreSettingsObserver.getCoreSettingsLocked());
5994            updateLruProcessLocked(app, false, null);
5995            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5996        } catch (Exception e) {
5997            // todo: Yikes!  What should we do?  For now we will try to
5998            // start another process, but that could easily get us in
5999            // an infinite loop of restarting processes...
6000            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6001
6002            app.resetPackageList(mProcessStats);
6003            app.unlinkDeathRecipient();
6004            startProcessLocked(app, "bind fail", processName);
6005            return false;
6006        }
6007
6008        // Remove this record from the list of starting applications.
6009        mPersistentStartingProcesses.remove(app);
6010        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6011                "Attach application locked removing on hold: " + app);
6012        mProcessesOnHold.remove(app);
6013
6014        boolean badApp = false;
6015        boolean didSomething = false;
6016
6017        // See if the top visible activity is waiting to run in this process...
6018        if (normalMode) {
6019            try {
6020                if (mStackSupervisor.attachApplicationLocked(app)) {
6021                    didSomething = true;
6022                }
6023            } catch (Exception e) {
6024                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6025                badApp = true;
6026            }
6027        }
6028
6029        // Find any services that should be running in this process...
6030        if (!badApp) {
6031            try {
6032                didSomething |= mServices.attachApplicationLocked(app, processName);
6033            } catch (Exception e) {
6034                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6035                badApp = true;
6036            }
6037        }
6038
6039        // Check if a next-broadcast receiver is in this process...
6040        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6041            try {
6042                didSomething |= sendPendingBroadcastsLocked(app);
6043            } catch (Exception e) {
6044                // If the app died trying to launch the receiver we declare it 'bad'
6045                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6046                badApp = true;
6047            }
6048        }
6049
6050        // Check whether the next backup agent is in this process...
6051        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6052            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6053            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6054            try {
6055                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6056                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6057                        mBackupTarget.backupMode);
6058            } catch (Exception e) {
6059                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6060                badApp = true;
6061            }
6062        }
6063
6064        if (badApp) {
6065            app.kill("error during init", true);
6066            handleAppDiedLocked(app, false, true);
6067            return false;
6068        }
6069
6070        if (!didSomething) {
6071            updateOomAdjLocked();
6072        }
6073
6074        return true;
6075    }
6076
6077    @Override
6078    public final void attachApplication(IApplicationThread thread) {
6079        synchronized (this) {
6080            int callingPid = Binder.getCallingPid();
6081            final long origId = Binder.clearCallingIdentity();
6082            attachApplicationLocked(thread, callingPid);
6083            Binder.restoreCallingIdentity(origId);
6084        }
6085    }
6086
6087    @Override
6088    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6089        final long origId = Binder.clearCallingIdentity();
6090        synchronized (this) {
6091            ActivityStack stack = ActivityRecord.getStackLocked(token);
6092            if (stack != null) {
6093                ActivityRecord r =
6094                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6095                if (stopProfiling) {
6096                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6097                        try {
6098                            mProfileFd.close();
6099                        } catch (IOException e) {
6100                        }
6101                        clearProfilerLocked();
6102                    }
6103                }
6104            }
6105        }
6106        Binder.restoreCallingIdentity(origId);
6107    }
6108
6109    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6110        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6111                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6112    }
6113
6114    void enableScreenAfterBoot() {
6115        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6116                SystemClock.uptimeMillis());
6117        mWindowManager.enableScreenAfterBoot();
6118
6119        synchronized (this) {
6120            updateEventDispatchingLocked();
6121        }
6122    }
6123
6124    @Override
6125    public void showBootMessage(final CharSequence msg, final boolean always) {
6126        enforceNotIsolatedCaller("showBootMessage");
6127        mWindowManager.showBootMessage(msg, always);
6128    }
6129
6130    @Override
6131    public void keyguardWaitingForActivityDrawn() {
6132        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6133        final long token = Binder.clearCallingIdentity();
6134        try {
6135            synchronized (this) {
6136                if (DEBUG_LOCKSCREEN) logLockScreen("");
6137                mWindowManager.keyguardWaitingForActivityDrawn();
6138                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6139                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6140                    updateSleepIfNeededLocked();
6141                }
6142            }
6143        } finally {
6144            Binder.restoreCallingIdentity(token);
6145        }
6146    }
6147
6148    final void finishBooting() {
6149        synchronized (this) {
6150            if (!mBootAnimationComplete) {
6151                mCallFinishBooting = true;
6152                return;
6153            }
6154            mCallFinishBooting = false;
6155        }
6156
6157        ArraySet<String> completedIsas = new ArraySet<String>();
6158        for (String abi : Build.SUPPORTED_ABIS) {
6159            Process.establishZygoteConnectionForAbi(abi);
6160            final String instructionSet = VMRuntime.getInstructionSet(abi);
6161            if (!completedIsas.contains(instructionSet)) {
6162                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6163                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6164                }
6165                completedIsas.add(instructionSet);
6166            }
6167        }
6168
6169        IntentFilter pkgFilter = new IntentFilter();
6170        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6171        pkgFilter.addDataScheme("package");
6172        mContext.registerReceiver(new BroadcastReceiver() {
6173            @Override
6174            public void onReceive(Context context, Intent intent) {
6175                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6176                if (pkgs != null) {
6177                    for (String pkg : pkgs) {
6178                        synchronized (ActivityManagerService.this) {
6179                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6180                                    0, "finished booting")) {
6181                                setResultCode(Activity.RESULT_OK);
6182                                return;
6183                            }
6184                        }
6185                    }
6186                }
6187            }
6188        }, pkgFilter);
6189
6190        // Let system services know.
6191        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6192
6193        synchronized (this) {
6194            // Ensure that any processes we had put on hold are now started
6195            // up.
6196            final int NP = mProcessesOnHold.size();
6197            if (NP > 0) {
6198                ArrayList<ProcessRecord> procs =
6199                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6200                for (int ip=0; ip<NP; ip++) {
6201                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6202                            + procs.get(ip));
6203                    startProcessLocked(procs.get(ip), "on-hold", null);
6204                }
6205            }
6206
6207            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6208                // Start looking for apps that are abusing wake locks.
6209                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6210                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6211                // Tell anyone interested that we are done booting!
6212                SystemProperties.set("sys.boot_completed", "1");
6213
6214                // And trigger dev.bootcomplete if we are not showing encryption progress
6215                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6216                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6217                    SystemProperties.set("dev.bootcomplete", "1");
6218                }
6219                for (int i=0; i<mStartedUsers.size(); i++) {
6220                    UserStartedState uss = mStartedUsers.valueAt(i);
6221                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6222                        uss.mState = UserStartedState.STATE_RUNNING;
6223                        final int userId = mStartedUsers.keyAt(i);
6224                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6225                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6226                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6227                        broadcastIntentLocked(null, null, intent, null,
6228                                new IIntentReceiver.Stub() {
6229                                    @Override
6230                                    public void performReceive(Intent intent, int resultCode,
6231                                            String data, Bundle extras, boolean ordered,
6232                                            boolean sticky, int sendingUser) {
6233                                        synchronized (ActivityManagerService.this) {
6234                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6235                                                    true, false);
6236                                        }
6237                                    }
6238                                },
6239                                0, null, null,
6240                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6241                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6242                                userId);
6243                    }
6244                }
6245                scheduleStartProfilesLocked();
6246            }
6247        }
6248    }
6249
6250    @Override
6251    public void bootAnimationComplete() {
6252        final boolean callFinishBooting;
6253        synchronized (this) {
6254            callFinishBooting = mCallFinishBooting;
6255            mBootAnimationComplete = true;
6256        }
6257        if (callFinishBooting) {
6258            finishBooting();
6259        }
6260    }
6261
6262    @Override
6263    public void systemBackupRestored() {
6264        synchronized (this) {
6265            if (mSystemReady) {
6266                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6267            } else {
6268                Slog.w(TAG, "System backup restored before system is ready");
6269            }
6270        }
6271    }
6272
6273    final void ensureBootCompleted() {
6274        boolean booting;
6275        boolean enableScreen;
6276        synchronized (this) {
6277            booting = mBooting;
6278            mBooting = false;
6279            enableScreen = !mBooted;
6280            mBooted = true;
6281        }
6282
6283        if (booting) {
6284            finishBooting();
6285        }
6286
6287        if (enableScreen) {
6288            enableScreenAfterBoot();
6289        }
6290    }
6291
6292    @Override
6293    public final void activityResumed(IBinder token) {
6294        final long origId = Binder.clearCallingIdentity();
6295        synchronized(this) {
6296            ActivityStack stack = ActivityRecord.getStackLocked(token);
6297            if (stack != null) {
6298                ActivityRecord.activityResumedLocked(token);
6299            }
6300        }
6301        Binder.restoreCallingIdentity(origId);
6302    }
6303
6304    @Override
6305    public final void activityPaused(IBinder token) {
6306        final long origId = Binder.clearCallingIdentity();
6307        synchronized(this) {
6308            ActivityStack stack = ActivityRecord.getStackLocked(token);
6309            if (stack != null) {
6310                stack.activityPausedLocked(token, false);
6311            }
6312        }
6313        Binder.restoreCallingIdentity(origId);
6314    }
6315
6316    @Override
6317    public final void activityStopped(IBinder token, Bundle icicle,
6318            PersistableBundle persistentState, CharSequence description) {
6319        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6320
6321        // Refuse possible leaked file descriptors
6322        if (icicle != null && icicle.hasFileDescriptors()) {
6323            throw new IllegalArgumentException("File descriptors passed in Bundle");
6324        }
6325
6326        final long origId = Binder.clearCallingIdentity();
6327
6328        synchronized (this) {
6329            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6330            if (r != null) {
6331                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6332            }
6333        }
6334
6335        trimApplications();
6336
6337        Binder.restoreCallingIdentity(origId);
6338    }
6339
6340    @Override
6341    public final void activityDestroyed(IBinder token) {
6342        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6343        synchronized (this) {
6344            ActivityStack stack = ActivityRecord.getStackLocked(token);
6345            if (stack != null) {
6346                stack.activityDestroyedLocked(token);
6347            }
6348        }
6349    }
6350
6351    @Override
6352    public final void backgroundResourcesReleased(IBinder token) {
6353        final long origId = Binder.clearCallingIdentity();
6354        try {
6355            synchronized (this) {
6356                ActivityStack stack = ActivityRecord.getStackLocked(token);
6357                if (stack != null) {
6358                    stack.backgroundResourcesReleased();
6359                }
6360            }
6361        } finally {
6362            Binder.restoreCallingIdentity(origId);
6363        }
6364    }
6365
6366    @Override
6367    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6368        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6369    }
6370
6371    @Override
6372    public final void notifyEnterAnimationComplete(IBinder token) {
6373        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6374    }
6375
6376    @Override
6377    public String getCallingPackage(IBinder token) {
6378        synchronized (this) {
6379            ActivityRecord r = getCallingRecordLocked(token);
6380            return r != null ? r.info.packageName : null;
6381        }
6382    }
6383
6384    @Override
6385    public ComponentName getCallingActivity(IBinder token) {
6386        synchronized (this) {
6387            ActivityRecord r = getCallingRecordLocked(token);
6388            return r != null ? r.intent.getComponent() : null;
6389        }
6390    }
6391
6392    private ActivityRecord getCallingRecordLocked(IBinder token) {
6393        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6394        if (r == null) {
6395            return null;
6396        }
6397        return r.resultTo;
6398    }
6399
6400    @Override
6401    public ComponentName getActivityClassForToken(IBinder token) {
6402        synchronized(this) {
6403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6404            if (r == null) {
6405                return null;
6406            }
6407            return r.intent.getComponent();
6408        }
6409    }
6410
6411    @Override
6412    public String getPackageForToken(IBinder token) {
6413        synchronized(this) {
6414            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6415            if (r == null) {
6416                return null;
6417            }
6418            return r.packageName;
6419        }
6420    }
6421
6422    @Override
6423    public IIntentSender getIntentSender(int type,
6424            String packageName, IBinder token, String resultWho,
6425            int requestCode, Intent[] intents, String[] resolvedTypes,
6426            int flags, Bundle options, int userId) {
6427        enforceNotIsolatedCaller("getIntentSender");
6428        // Refuse possible leaked file descriptors
6429        if (intents != null) {
6430            if (intents.length < 1) {
6431                throw new IllegalArgumentException("Intents array length must be >= 1");
6432            }
6433            for (int i=0; i<intents.length; i++) {
6434                Intent intent = intents[i];
6435                if (intent != null) {
6436                    if (intent.hasFileDescriptors()) {
6437                        throw new IllegalArgumentException("File descriptors passed in Intent");
6438                    }
6439                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6440                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6441                        throw new IllegalArgumentException(
6442                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6443                    }
6444                    intents[i] = new Intent(intent);
6445                }
6446            }
6447            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6448                throw new IllegalArgumentException(
6449                        "Intent array length does not match resolvedTypes length");
6450            }
6451        }
6452        if (options != null) {
6453            if (options.hasFileDescriptors()) {
6454                throw new IllegalArgumentException("File descriptors passed in options");
6455            }
6456        }
6457
6458        synchronized(this) {
6459            int callingUid = Binder.getCallingUid();
6460            int origUserId = userId;
6461            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6462                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6463                    ALLOW_NON_FULL, "getIntentSender", null);
6464            if (origUserId == UserHandle.USER_CURRENT) {
6465                // We don't want to evaluate this until the pending intent is
6466                // actually executed.  However, we do want to always do the
6467                // security checking for it above.
6468                userId = UserHandle.USER_CURRENT;
6469            }
6470            try {
6471                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6472                    int uid = AppGlobals.getPackageManager()
6473                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6474                    if (!UserHandle.isSameApp(callingUid, uid)) {
6475                        String msg = "Permission Denial: getIntentSender() from pid="
6476                            + Binder.getCallingPid()
6477                            + ", uid=" + Binder.getCallingUid()
6478                            + ", (need uid=" + uid + ")"
6479                            + " is not allowed to send as package " + packageName;
6480                        Slog.w(TAG, msg);
6481                        throw new SecurityException(msg);
6482                    }
6483                }
6484
6485                return getIntentSenderLocked(type, packageName, callingUid, userId,
6486                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6487
6488            } catch (RemoteException e) {
6489                throw new SecurityException(e);
6490            }
6491        }
6492    }
6493
6494    IIntentSender getIntentSenderLocked(int type, String packageName,
6495            int callingUid, int userId, IBinder token, String resultWho,
6496            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6497            Bundle options) {
6498        if (DEBUG_MU)
6499            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6500        ActivityRecord activity = null;
6501        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6502            activity = ActivityRecord.isInStackLocked(token);
6503            if (activity == null) {
6504                return null;
6505            }
6506            if (activity.finishing) {
6507                return null;
6508            }
6509        }
6510
6511        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6512        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6513        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6514        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6515                |PendingIntent.FLAG_UPDATE_CURRENT);
6516
6517        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6518                type, packageName, activity, resultWho,
6519                requestCode, intents, resolvedTypes, flags, options, userId);
6520        WeakReference<PendingIntentRecord> ref;
6521        ref = mIntentSenderRecords.get(key);
6522        PendingIntentRecord rec = ref != null ? ref.get() : null;
6523        if (rec != null) {
6524            if (!cancelCurrent) {
6525                if (updateCurrent) {
6526                    if (rec.key.requestIntent != null) {
6527                        rec.key.requestIntent.replaceExtras(intents != null ?
6528                                intents[intents.length - 1] : null);
6529                    }
6530                    if (intents != null) {
6531                        intents[intents.length-1] = rec.key.requestIntent;
6532                        rec.key.allIntents = intents;
6533                        rec.key.allResolvedTypes = resolvedTypes;
6534                    } else {
6535                        rec.key.allIntents = null;
6536                        rec.key.allResolvedTypes = null;
6537                    }
6538                }
6539                return rec;
6540            }
6541            rec.canceled = true;
6542            mIntentSenderRecords.remove(key);
6543        }
6544        if (noCreate) {
6545            return rec;
6546        }
6547        rec = new PendingIntentRecord(this, key, callingUid);
6548        mIntentSenderRecords.put(key, rec.ref);
6549        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6550            if (activity.pendingResults == null) {
6551                activity.pendingResults
6552                        = new HashSet<WeakReference<PendingIntentRecord>>();
6553            }
6554            activity.pendingResults.add(rec.ref);
6555        }
6556        return rec;
6557    }
6558
6559    @Override
6560    public void cancelIntentSender(IIntentSender sender) {
6561        if (!(sender instanceof PendingIntentRecord)) {
6562            return;
6563        }
6564        synchronized(this) {
6565            PendingIntentRecord rec = (PendingIntentRecord)sender;
6566            try {
6567                int uid = AppGlobals.getPackageManager()
6568                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6569                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6570                    String msg = "Permission Denial: cancelIntentSender() from pid="
6571                        + Binder.getCallingPid()
6572                        + ", uid=" + Binder.getCallingUid()
6573                        + " is not allowed to cancel packges "
6574                        + rec.key.packageName;
6575                    Slog.w(TAG, msg);
6576                    throw new SecurityException(msg);
6577                }
6578            } catch (RemoteException e) {
6579                throw new SecurityException(e);
6580            }
6581            cancelIntentSenderLocked(rec, true);
6582        }
6583    }
6584
6585    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6586        rec.canceled = true;
6587        mIntentSenderRecords.remove(rec.key);
6588        if (cleanActivity && rec.key.activity != null) {
6589            rec.key.activity.pendingResults.remove(rec.ref);
6590        }
6591    }
6592
6593    @Override
6594    public String getPackageForIntentSender(IIntentSender pendingResult) {
6595        if (!(pendingResult instanceof PendingIntentRecord)) {
6596            return null;
6597        }
6598        try {
6599            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6600            return res.key.packageName;
6601        } catch (ClassCastException e) {
6602        }
6603        return null;
6604    }
6605
6606    @Override
6607    public int getUidForIntentSender(IIntentSender sender) {
6608        if (sender instanceof PendingIntentRecord) {
6609            try {
6610                PendingIntentRecord res = (PendingIntentRecord)sender;
6611                return res.uid;
6612            } catch (ClassCastException e) {
6613            }
6614        }
6615        return -1;
6616    }
6617
6618    @Override
6619    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6620        if (!(pendingResult instanceof PendingIntentRecord)) {
6621            return false;
6622        }
6623        try {
6624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6625            if (res.key.allIntents == null) {
6626                return false;
6627            }
6628            for (int i=0; i<res.key.allIntents.length; i++) {
6629                Intent intent = res.key.allIntents[i];
6630                if (intent.getPackage() != null && intent.getComponent() != null) {
6631                    return false;
6632                }
6633            }
6634            return true;
6635        } catch (ClassCastException e) {
6636        }
6637        return false;
6638    }
6639
6640    @Override
6641    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6642        if (!(pendingResult instanceof PendingIntentRecord)) {
6643            return false;
6644        }
6645        try {
6646            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6647            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6648                return true;
6649            }
6650            return false;
6651        } catch (ClassCastException e) {
6652        }
6653        return false;
6654    }
6655
6656    @Override
6657    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6658        if (!(pendingResult instanceof PendingIntentRecord)) {
6659            return null;
6660        }
6661        try {
6662            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6663            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6664        } catch (ClassCastException e) {
6665        }
6666        return null;
6667    }
6668
6669    @Override
6670    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6671        if (!(pendingResult instanceof PendingIntentRecord)) {
6672            return null;
6673        }
6674        try {
6675            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6676            Intent intent = res.key.requestIntent;
6677            if (intent != null) {
6678                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6679                        || res.lastTagPrefix.equals(prefix))) {
6680                    return res.lastTag;
6681                }
6682                res.lastTagPrefix = prefix;
6683                StringBuilder sb = new StringBuilder(128);
6684                if (prefix != null) {
6685                    sb.append(prefix);
6686                }
6687                if (intent.getAction() != null) {
6688                    sb.append(intent.getAction());
6689                } else if (intent.getComponent() != null) {
6690                    intent.getComponent().appendShortString(sb);
6691                } else {
6692                    sb.append("?");
6693                }
6694                return res.lastTag = sb.toString();
6695            }
6696        } catch (ClassCastException e) {
6697        }
6698        return null;
6699    }
6700
6701    @Override
6702    public void setProcessLimit(int max) {
6703        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6704                "setProcessLimit()");
6705        synchronized (this) {
6706            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6707            mProcessLimitOverride = max;
6708        }
6709        trimApplications();
6710    }
6711
6712    @Override
6713    public int getProcessLimit() {
6714        synchronized (this) {
6715            return mProcessLimitOverride;
6716        }
6717    }
6718
6719    void foregroundTokenDied(ForegroundToken token) {
6720        synchronized (ActivityManagerService.this) {
6721            synchronized (mPidsSelfLocked) {
6722                ForegroundToken cur
6723                    = mForegroundProcesses.get(token.pid);
6724                if (cur != token) {
6725                    return;
6726                }
6727                mForegroundProcesses.remove(token.pid);
6728                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6729                if (pr == null) {
6730                    return;
6731                }
6732                pr.forcingToForeground = null;
6733                updateProcessForegroundLocked(pr, false, false);
6734            }
6735            updateOomAdjLocked();
6736        }
6737    }
6738
6739    @Override
6740    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6741        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6742                "setProcessForeground()");
6743        synchronized(this) {
6744            boolean changed = false;
6745
6746            synchronized (mPidsSelfLocked) {
6747                ProcessRecord pr = mPidsSelfLocked.get(pid);
6748                if (pr == null && isForeground) {
6749                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6750                    return;
6751                }
6752                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6753                if (oldToken != null) {
6754                    oldToken.token.unlinkToDeath(oldToken, 0);
6755                    mForegroundProcesses.remove(pid);
6756                    if (pr != null) {
6757                        pr.forcingToForeground = null;
6758                    }
6759                    changed = true;
6760                }
6761                if (isForeground && token != null) {
6762                    ForegroundToken newToken = new ForegroundToken() {
6763                        @Override
6764                        public void binderDied() {
6765                            foregroundTokenDied(this);
6766                        }
6767                    };
6768                    newToken.pid = pid;
6769                    newToken.token = token;
6770                    try {
6771                        token.linkToDeath(newToken, 0);
6772                        mForegroundProcesses.put(pid, newToken);
6773                        pr.forcingToForeground = token;
6774                        changed = true;
6775                    } catch (RemoteException e) {
6776                        // If the process died while doing this, we will later
6777                        // do the cleanup with the process death link.
6778                    }
6779                }
6780            }
6781
6782            if (changed) {
6783                updateOomAdjLocked();
6784            }
6785        }
6786    }
6787
6788    // =========================================================
6789    // PERMISSIONS
6790    // =========================================================
6791
6792    static class PermissionController extends IPermissionController.Stub {
6793        ActivityManagerService mActivityManagerService;
6794        PermissionController(ActivityManagerService activityManagerService) {
6795            mActivityManagerService = activityManagerService;
6796        }
6797
6798        @Override
6799        public boolean checkPermission(String permission, int pid, int uid) {
6800            return mActivityManagerService.checkPermission(permission, pid,
6801                    uid) == PackageManager.PERMISSION_GRANTED;
6802        }
6803    }
6804
6805    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6806        @Override
6807        public int checkComponentPermission(String permission, int pid, int uid,
6808                int owningUid, boolean exported) {
6809            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6810                    owningUid, exported);
6811        }
6812
6813        @Override
6814        public Object getAMSLock() {
6815            return ActivityManagerService.this;
6816        }
6817    }
6818
6819    /**
6820     * This can be called with or without the global lock held.
6821     */
6822    int checkComponentPermission(String permission, int pid, int uid,
6823            int owningUid, boolean exported) {
6824        if (pid == MY_PID) {
6825            return PackageManager.PERMISSION_GRANTED;
6826        }
6827        return ActivityManager.checkComponentPermission(permission, uid,
6828                owningUid, exported);
6829    }
6830
6831    /**
6832     * As the only public entry point for permissions checking, this method
6833     * can enforce the semantic that requesting a check on a null global
6834     * permission is automatically denied.  (Internally a null permission
6835     * string is used when calling {@link #checkComponentPermission} in cases
6836     * when only uid-based security is needed.)
6837     *
6838     * This can be called with or without the global lock held.
6839     */
6840    @Override
6841    public int checkPermission(String permission, int pid, int uid) {
6842        if (permission == null) {
6843            return PackageManager.PERMISSION_DENIED;
6844        }
6845        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6846    }
6847
6848    @Override
6849    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6850        if (permission == null) {
6851            return PackageManager.PERMISSION_DENIED;
6852        }
6853
6854        // We might be performing an operation on behalf of an indirect binder
6855        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6856        // client identity accordingly before proceeding.
6857        Identity tlsIdentity = sCallerIdentity.get();
6858        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6859            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6860                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6861            uid = tlsIdentity.uid;
6862            pid = tlsIdentity.pid;
6863        }
6864
6865        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6866    }
6867
6868    /**
6869     * Binder IPC calls go through the public entry point.
6870     * This can be called with or without the global lock held.
6871     */
6872    int checkCallingPermission(String permission) {
6873        return checkPermission(permission,
6874                Binder.getCallingPid(),
6875                UserHandle.getAppId(Binder.getCallingUid()));
6876    }
6877
6878    /**
6879     * This can be called with or without the global lock held.
6880     */
6881    void enforceCallingPermission(String permission, String func) {
6882        if (checkCallingPermission(permission)
6883                == PackageManager.PERMISSION_GRANTED) {
6884            return;
6885        }
6886
6887        String msg = "Permission Denial: " + func + " from pid="
6888                + Binder.getCallingPid()
6889                + ", uid=" + Binder.getCallingUid()
6890                + " requires " + permission;
6891        Slog.w(TAG, msg);
6892        throw new SecurityException(msg);
6893    }
6894
6895    /**
6896     * Determine if UID is holding permissions required to access {@link Uri} in
6897     * the given {@link ProviderInfo}. Final permission checking is always done
6898     * in {@link ContentProvider}.
6899     */
6900    private final boolean checkHoldingPermissionsLocked(
6901            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6902        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6903                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6904        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6905            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6906                    != PERMISSION_GRANTED) {
6907                return false;
6908            }
6909        }
6910        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6911    }
6912
6913    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6914            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6915        if (pi.applicationInfo.uid == uid) {
6916            return true;
6917        } else if (!pi.exported) {
6918            return false;
6919        }
6920
6921        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6922        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6923        try {
6924            // check if target holds top-level <provider> permissions
6925            if (!readMet && pi.readPermission != null && considerUidPermissions
6926                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6927                readMet = true;
6928            }
6929            if (!writeMet && pi.writePermission != null && considerUidPermissions
6930                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6931                writeMet = true;
6932            }
6933
6934            // track if unprotected read/write is allowed; any denied
6935            // <path-permission> below removes this ability
6936            boolean allowDefaultRead = pi.readPermission == null;
6937            boolean allowDefaultWrite = pi.writePermission == null;
6938
6939            // check if target holds any <path-permission> that match uri
6940            final PathPermission[] pps = pi.pathPermissions;
6941            if (pps != null) {
6942                final String path = grantUri.uri.getPath();
6943                int i = pps.length;
6944                while (i > 0 && (!readMet || !writeMet)) {
6945                    i--;
6946                    PathPermission pp = pps[i];
6947                    if (pp.match(path)) {
6948                        if (!readMet) {
6949                            final String pprperm = pp.getReadPermission();
6950                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6951                                    + pprperm + " for " + pp.getPath()
6952                                    + ": match=" + pp.match(path)
6953                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6954                            if (pprperm != null) {
6955                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6956                                        == PERMISSION_GRANTED) {
6957                                    readMet = true;
6958                                } else {
6959                                    allowDefaultRead = false;
6960                                }
6961                            }
6962                        }
6963                        if (!writeMet) {
6964                            final String ppwperm = pp.getWritePermission();
6965                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6966                                    + ppwperm + " for " + pp.getPath()
6967                                    + ": match=" + pp.match(path)
6968                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6969                            if (ppwperm != null) {
6970                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6971                                        == PERMISSION_GRANTED) {
6972                                    writeMet = true;
6973                                } else {
6974                                    allowDefaultWrite = false;
6975                                }
6976                            }
6977                        }
6978                    }
6979                }
6980            }
6981
6982            // grant unprotected <provider> read/write, if not blocked by
6983            // <path-permission> above
6984            if (allowDefaultRead) readMet = true;
6985            if (allowDefaultWrite) writeMet = true;
6986
6987        } catch (RemoteException e) {
6988            return false;
6989        }
6990
6991        return readMet && writeMet;
6992    }
6993
6994    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6995        ProviderInfo pi = null;
6996        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6997        if (cpr != null) {
6998            pi = cpr.info;
6999        } else {
7000            try {
7001                pi = AppGlobals.getPackageManager().resolveContentProvider(
7002                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7003            } catch (RemoteException ex) {
7004            }
7005        }
7006        return pi;
7007    }
7008
7009    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7010        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7011        if (targetUris != null) {
7012            return targetUris.get(grantUri);
7013        }
7014        return null;
7015    }
7016
7017    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7018            String targetPkg, int targetUid, GrantUri grantUri) {
7019        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7020        if (targetUris == null) {
7021            targetUris = Maps.newArrayMap();
7022            mGrantedUriPermissions.put(targetUid, targetUris);
7023        }
7024
7025        UriPermission perm = targetUris.get(grantUri);
7026        if (perm == null) {
7027            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7028            targetUris.put(grantUri, perm);
7029        }
7030
7031        return perm;
7032    }
7033
7034    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7035            final int modeFlags) {
7036        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7037        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7038                : UriPermission.STRENGTH_OWNED;
7039
7040        // Root gets to do everything.
7041        if (uid == 0) {
7042            return true;
7043        }
7044
7045        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7046        if (perms == null) return false;
7047
7048        // First look for exact match
7049        final UriPermission exactPerm = perms.get(grantUri);
7050        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7051            return true;
7052        }
7053
7054        // No exact match, look for prefixes
7055        final int N = perms.size();
7056        for (int i = 0; i < N; i++) {
7057            final UriPermission perm = perms.valueAt(i);
7058            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7059                    && perm.getStrength(modeFlags) >= minStrength) {
7060                return true;
7061            }
7062        }
7063
7064        return false;
7065    }
7066
7067    /**
7068     * @param uri This uri must NOT contain an embedded userId.
7069     * @param userId The userId in which the uri is to be resolved.
7070     */
7071    @Override
7072    public int checkUriPermission(Uri uri, int pid, int uid,
7073            final int modeFlags, int userId, IBinder callerToken) {
7074        enforceNotIsolatedCaller("checkUriPermission");
7075
7076        // Another redirected-binder-call permissions check as in
7077        // {@link checkPermissionWithToken}.
7078        Identity tlsIdentity = sCallerIdentity.get();
7079        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7080            uid = tlsIdentity.uid;
7081            pid = tlsIdentity.pid;
7082        }
7083
7084        // Our own process gets to do everything.
7085        if (pid == MY_PID) {
7086            return PackageManager.PERMISSION_GRANTED;
7087        }
7088        synchronized (this) {
7089            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7090                    ? PackageManager.PERMISSION_GRANTED
7091                    : PackageManager.PERMISSION_DENIED;
7092        }
7093    }
7094
7095    /**
7096     * Check if the targetPkg can be granted permission to access uri by
7097     * the callingUid using the given modeFlags.  Throws a security exception
7098     * if callingUid is not allowed to do this.  Returns the uid of the target
7099     * if the URI permission grant should be performed; returns -1 if it is not
7100     * needed (for example targetPkg already has permission to access the URI).
7101     * If you already know the uid of the target, you can supply it in
7102     * lastTargetUid else set that to -1.
7103     */
7104    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7105            final int modeFlags, int lastTargetUid) {
7106        if (!Intent.isAccessUriMode(modeFlags)) {
7107            return -1;
7108        }
7109
7110        if (targetPkg != null) {
7111            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7112                    "Checking grant " + targetPkg + " permission to " + grantUri);
7113        }
7114
7115        final IPackageManager pm = AppGlobals.getPackageManager();
7116
7117        // If this is not a content: uri, we can't do anything with it.
7118        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7119            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7120                    "Can't grant URI permission for non-content URI: " + grantUri);
7121            return -1;
7122        }
7123
7124        final String authority = grantUri.uri.getAuthority();
7125        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7126        if (pi == null) {
7127            Slog.w(TAG, "No content provider found for permission check: " +
7128                    grantUri.uri.toSafeString());
7129            return -1;
7130        }
7131
7132        int targetUid = lastTargetUid;
7133        if (targetUid < 0 && targetPkg != null) {
7134            try {
7135                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7136                if (targetUid < 0) {
7137                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7138                            "Can't grant URI permission no uid for: " + targetPkg);
7139                    return -1;
7140                }
7141            } catch (RemoteException ex) {
7142                return -1;
7143            }
7144        }
7145
7146        if (targetUid >= 0) {
7147            // First...  does the target actually need this permission?
7148            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7149                // No need to grant the target this permission.
7150                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7151                        "Target " + targetPkg + " already has full permission to " + grantUri);
7152                return -1;
7153            }
7154        } else {
7155            // First...  there is no target package, so can anyone access it?
7156            boolean allowed = pi.exported;
7157            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7158                if (pi.readPermission != null) {
7159                    allowed = false;
7160                }
7161            }
7162            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7163                if (pi.writePermission != null) {
7164                    allowed = false;
7165                }
7166            }
7167            if (allowed) {
7168                return -1;
7169            }
7170        }
7171
7172        /* There is a special cross user grant if:
7173         * - The target is on another user.
7174         * - Apps on the current user can access the uri without any uid permissions.
7175         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7176         * grant uri permissions.
7177         */
7178        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7179                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7180                modeFlags, false /*without considering the uid permissions*/);
7181
7182        // Second...  is the provider allowing granting of URI permissions?
7183        if (!specialCrossUserGrant) {
7184            if (!pi.grantUriPermissions) {
7185                throw new SecurityException("Provider " + pi.packageName
7186                        + "/" + pi.name
7187                        + " does not allow granting of Uri permissions (uri "
7188                        + grantUri + ")");
7189            }
7190            if (pi.uriPermissionPatterns != null) {
7191                final int N = pi.uriPermissionPatterns.length;
7192                boolean allowed = false;
7193                for (int i=0; i<N; i++) {
7194                    if (pi.uriPermissionPatterns[i] != null
7195                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7196                        allowed = true;
7197                        break;
7198                    }
7199                }
7200                if (!allowed) {
7201                    throw new SecurityException("Provider " + pi.packageName
7202                            + "/" + pi.name
7203                            + " does not allow granting of permission to path of Uri "
7204                            + grantUri);
7205                }
7206            }
7207        }
7208
7209        // Third...  does the caller itself have permission to access
7210        // this uri?
7211        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7212            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7213                // Require they hold a strong enough Uri permission
7214                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7215                    throw new SecurityException("Uid " + callingUid
7216                            + " does not have permission to uri " + grantUri);
7217                }
7218            }
7219        }
7220        return targetUid;
7221    }
7222
7223    /**
7224     * @param uri This uri must NOT contain an embedded userId.
7225     * @param userId The userId in which the uri is to be resolved.
7226     */
7227    @Override
7228    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7229            final int modeFlags, int userId) {
7230        enforceNotIsolatedCaller("checkGrantUriPermission");
7231        synchronized(this) {
7232            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7233                    new GrantUri(userId, uri, false), modeFlags, -1);
7234        }
7235    }
7236
7237    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7238            final int modeFlags, UriPermissionOwner owner) {
7239        if (!Intent.isAccessUriMode(modeFlags)) {
7240            return;
7241        }
7242
7243        // So here we are: the caller has the assumed permission
7244        // to the uri, and the target doesn't.  Let's now give this to
7245        // the target.
7246
7247        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7248                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7249
7250        final String authority = grantUri.uri.getAuthority();
7251        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7252        if (pi == null) {
7253            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7254            return;
7255        }
7256
7257        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7258            grantUri.prefix = true;
7259        }
7260        final UriPermission perm = findOrCreateUriPermissionLocked(
7261                pi.packageName, targetPkg, targetUid, grantUri);
7262        perm.grantModes(modeFlags, owner);
7263    }
7264
7265    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7266            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7267        if (targetPkg == null) {
7268            throw new NullPointerException("targetPkg");
7269        }
7270        int targetUid;
7271        final IPackageManager pm = AppGlobals.getPackageManager();
7272        try {
7273            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7274        } catch (RemoteException ex) {
7275            return;
7276        }
7277
7278        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7279                targetUid);
7280        if (targetUid < 0) {
7281            return;
7282        }
7283
7284        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7285                owner);
7286    }
7287
7288    static class NeededUriGrants extends ArrayList<GrantUri> {
7289        final String targetPkg;
7290        final int targetUid;
7291        final int flags;
7292
7293        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7294            this.targetPkg = targetPkg;
7295            this.targetUid = targetUid;
7296            this.flags = flags;
7297        }
7298    }
7299
7300    /**
7301     * Like checkGrantUriPermissionLocked, but takes an Intent.
7302     */
7303    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7304            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7305        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7306                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7307                + " clip=" + (intent != null ? intent.getClipData() : null)
7308                + " from " + intent + "; flags=0x"
7309                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7310
7311        if (targetPkg == null) {
7312            throw new NullPointerException("targetPkg");
7313        }
7314
7315        if (intent == null) {
7316            return null;
7317        }
7318        Uri data = intent.getData();
7319        ClipData clip = intent.getClipData();
7320        if (data == null && clip == null) {
7321            return null;
7322        }
7323        // Default userId for uris in the intent (if they don't specify it themselves)
7324        int contentUserHint = intent.getContentUserHint();
7325        if (contentUserHint == UserHandle.USER_CURRENT) {
7326            contentUserHint = UserHandle.getUserId(callingUid);
7327        }
7328        final IPackageManager pm = AppGlobals.getPackageManager();
7329        int targetUid;
7330        if (needed != null) {
7331            targetUid = needed.targetUid;
7332        } else {
7333            try {
7334                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7335            } catch (RemoteException ex) {
7336                return null;
7337            }
7338            if (targetUid < 0) {
7339                if (DEBUG_URI_PERMISSION) {
7340                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7341                            + " on user " + targetUserId);
7342                }
7343                return null;
7344            }
7345        }
7346        if (data != null) {
7347            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7348            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7349                    targetUid);
7350            if (targetUid > 0) {
7351                if (needed == null) {
7352                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7353                }
7354                needed.add(grantUri);
7355            }
7356        }
7357        if (clip != null) {
7358            for (int i=0; i<clip.getItemCount(); i++) {
7359                Uri uri = clip.getItemAt(i).getUri();
7360                if (uri != null) {
7361                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7362                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7363                            targetUid);
7364                    if (targetUid > 0) {
7365                        if (needed == null) {
7366                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7367                        }
7368                        needed.add(grantUri);
7369                    }
7370                } else {
7371                    Intent clipIntent = clip.getItemAt(i).getIntent();
7372                    if (clipIntent != null) {
7373                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7374                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7375                        if (newNeeded != null) {
7376                            needed = newNeeded;
7377                        }
7378                    }
7379                }
7380            }
7381        }
7382
7383        return needed;
7384    }
7385
7386    /**
7387     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7388     */
7389    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7390            UriPermissionOwner owner) {
7391        if (needed != null) {
7392            for (int i=0; i<needed.size(); i++) {
7393                GrantUri grantUri = needed.get(i);
7394                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7395                        grantUri, needed.flags, owner);
7396            }
7397        }
7398    }
7399
7400    void grantUriPermissionFromIntentLocked(int callingUid,
7401            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7402        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7403                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7404        if (needed == null) {
7405            return;
7406        }
7407
7408        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7409    }
7410
7411    /**
7412     * @param uri This uri must NOT contain an embedded userId.
7413     * @param userId The userId in which the uri is to be resolved.
7414     */
7415    @Override
7416    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7417            final int modeFlags, int userId) {
7418        enforceNotIsolatedCaller("grantUriPermission");
7419        GrantUri grantUri = new GrantUri(userId, uri, false);
7420        synchronized(this) {
7421            final ProcessRecord r = getRecordForAppLocked(caller);
7422            if (r == null) {
7423                throw new SecurityException("Unable to find app for caller "
7424                        + caller
7425                        + " when granting permission to uri " + grantUri);
7426            }
7427            if (targetPkg == null) {
7428                throw new IllegalArgumentException("null target");
7429            }
7430            if (grantUri == null) {
7431                throw new IllegalArgumentException("null uri");
7432            }
7433
7434            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7435                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7436                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7437                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7438
7439            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7440                    UserHandle.getUserId(r.uid));
7441        }
7442    }
7443
7444    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7445        if (perm.modeFlags == 0) {
7446            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7447                    perm.targetUid);
7448            if (perms != null) {
7449                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7450                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7451
7452                perms.remove(perm.uri);
7453                if (perms.isEmpty()) {
7454                    mGrantedUriPermissions.remove(perm.targetUid);
7455                }
7456            }
7457        }
7458    }
7459
7460    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7461        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7462
7463        final IPackageManager pm = AppGlobals.getPackageManager();
7464        final String authority = grantUri.uri.getAuthority();
7465        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7466        if (pi == null) {
7467            Slog.w(TAG, "No content provider found for permission revoke: "
7468                    + grantUri.toSafeString());
7469            return;
7470        }
7471
7472        // Does the caller have this permission on the URI?
7473        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7474            // If they don't have direct access to the URI, then revoke any
7475            // ownerless URI permissions that have been granted to them.
7476            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7477            if (perms != null) {
7478                boolean persistChanged = false;
7479                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7480                    final UriPermission perm = it.next();
7481                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7482                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7483                        if (DEBUG_URI_PERMISSION)
7484                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7485                                    " permission to " + perm.uri);
7486                        persistChanged |= perm.revokeModes(
7487                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7488                        if (perm.modeFlags == 0) {
7489                            it.remove();
7490                        }
7491                    }
7492                }
7493                if (perms.isEmpty()) {
7494                    mGrantedUriPermissions.remove(callingUid);
7495                }
7496                if (persistChanged) {
7497                    schedulePersistUriGrants();
7498                }
7499            }
7500            return;
7501        }
7502
7503        boolean persistChanged = false;
7504
7505        // Go through all of the permissions and remove any that match.
7506        int N = mGrantedUriPermissions.size();
7507        for (int i = 0; i < N; i++) {
7508            final int targetUid = mGrantedUriPermissions.keyAt(i);
7509            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7510
7511            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7512                final UriPermission perm = it.next();
7513                if (perm.uri.sourceUserId == grantUri.sourceUserId
7514                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7515                    if (DEBUG_URI_PERMISSION)
7516                        Slog.v(TAG,
7517                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7518                    persistChanged |= perm.revokeModes(
7519                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7520                    if (perm.modeFlags == 0) {
7521                        it.remove();
7522                    }
7523                }
7524            }
7525
7526            if (perms.isEmpty()) {
7527                mGrantedUriPermissions.remove(targetUid);
7528                N--;
7529                i--;
7530            }
7531        }
7532
7533        if (persistChanged) {
7534            schedulePersistUriGrants();
7535        }
7536    }
7537
7538    /**
7539     * @param uri This uri must NOT contain an embedded userId.
7540     * @param userId The userId in which the uri is to be resolved.
7541     */
7542    @Override
7543    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7544            int userId) {
7545        enforceNotIsolatedCaller("revokeUriPermission");
7546        synchronized(this) {
7547            final ProcessRecord r = getRecordForAppLocked(caller);
7548            if (r == null) {
7549                throw new SecurityException("Unable to find app for caller "
7550                        + caller
7551                        + " when revoking permission to uri " + uri);
7552            }
7553            if (uri == null) {
7554                Slog.w(TAG, "revokeUriPermission: null uri");
7555                return;
7556            }
7557
7558            if (!Intent.isAccessUriMode(modeFlags)) {
7559                return;
7560            }
7561
7562            final IPackageManager pm = AppGlobals.getPackageManager();
7563            final String authority = uri.getAuthority();
7564            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7565            if (pi == null) {
7566                Slog.w(TAG, "No content provider found for permission revoke: "
7567                        + uri.toSafeString());
7568                return;
7569            }
7570
7571            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7572        }
7573    }
7574
7575    /**
7576     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7577     * given package.
7578     *
7579     * @param packageName Package name to match, or {@code null} to apply to all
7580     *            packages.
7581     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7582     *            to all users.
7583     * @param persistable If persistable grants should be removed.
7584     */
7585    private void removeUriPermissionsForPackageLocked(
7586            String packageName, int userHandle, boolean persistable) {
7587        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7588            throw new IllegalArgumentException("Must narrow by either package or user");
7589        }
7590
7591        boolean persistChanged = false;
7592
7593        int N = mGrantedUriPermissions.size();
7594        for (int i = 0; i < N; i++) {
7595            final int targetUid = mGrantedUriPermissions.keyAt(i);
7596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7597
7598            // Only inspect grants matching user
7599            if (userHandle == UserHandle.USER_ALL
7600                    || userHandle == UserHandle.getUserId(targetUid)) {
7601                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7602                    final UriPermission perm = it.next();
7603
7604                    // Only inspect grants matching package
7605                    if (packageName == null || perm.sourcePkg.equals(packageName)
7606                            || perm.targetPkg.equals(packageName)) {
7607                        persistChanged |= perm.revokeModes(persistable
7608                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7609
7610                        // Only remove when no modes remain; any persisted grants
7611                        // will keep this alive.
7612                        if (perm.modeFlags == 0) {
7613                            it.remove();
7614                        }
7615                    }
7616                }
7617
7618                if (perms.isEmpty()) {
7619                    mGrantedUriPermissions.remove(targetUid);
7620                    N--;
7621                    i--;
7622                }
7623            }
7624        }
7625
7626        if (persistChanged) {
7627            schedulePersistUriGrants();
7628        }
7629    }
7630
7631    @Override
7632    public IBinder newUriPermissionOwner(String name) {
7633        enforceNotIsolatedCaller("newUriPermissionOwner");
7634        synchronized(this) {
7635            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7636            return owner.getExternalTokenLocked();
7637        }
7638    }
7639
7640    /**
7641     * @param uri This uri must NOT contain an embedded userId.
7642     * @param sourceUserId The userId in which the uri is to be resolved.
7643     * @param targetUserId The userId of the app that receives the grant.
7644     */
7645    @Override
7646    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7647            final int modeFlags, int sourceUserId, int targetUserId) {
7648        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7649                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7650        synchronized(this) {
7651            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7652            if (owner == null) {
7653                throw new IllegalArgumentException("Unknown owner: " + token);
7654            }
7655            if (fromUid != Binder.getCallingUid()) {
7656                if (Binder.getCallingUid() != Process.myUid()) {
7657                    // Only system code can grant URI permissions on behalf
7658                    // of other users.
7659                    throw new SecurityException("nice try");
7660                }
7661            }
7662            if (targetPkg == null) {
7663                throw new IllegalArgumentException("null target");
7664            }
7665            if (uri == null) {
7666                throw new IllegalArgumentException("null uri");
7667            }
7668
7669            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7670                    modeFlags, owner, targetUserId);
7671        }
7672    }
7673
7674    /**
7675     * @param uri This uri must NOT contain an embedded userId.
7676     * @param userId The userId in which the uri is to be resolved.
7677     */
7678    @Override
7679    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7680        synchronized(this) {
7681            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7682            if (owner == null) {
7683                throw new IllegalArgumentException("Unknown owner: " + token);
7684            }
7685
7686            if (uri == null) {
7687                owner.removeUriPermissionsLocked(mode);
7688            } else {
7689                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7690            }
7691        }
7692    }
7693
7694    private void schedulePersistUriGrants() {
7695        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7696            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7697                    10 * DateUtils.SECOND_IN_MILLIS);
7698        }
7699    }
7700
7701    private void writeGrantedUriPermissions() {
7702        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7703
7704        // Snapshot permissions so we can persist without lock
7705        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7706        synchronized (this) {
7707            final int size = mGrantedUriPermissions.size();
7708            for (int i = 0; i < size; i++) {
7709                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7710                for (UriPermission perm : perms.values()) {
7711                    if (perm.persistedModeFlags != 0) {
7712                        persist.add(perm.snapshot());
7713                    }
7714                }
7715            }
7716        }
7717
7718        FileOutputStream fos = null;
7719        try {
7720            fos = mGrantFile.startWrite();
7721
7722            XmlSerializer out = new FastXmlSerializer();
7723            out.setOutput(fos, "utf-8");
7724            out.startDocument(null, true);
7725            out.startTag(null, TAG_URI_GRANTS);
7726            for (UriPermission.Snapshot perm : persist) {
7727                out.startTag(null, TAG_URI_GRANT);
7728                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7729                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7730                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7731                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7732                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7733                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7734                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7735                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7736                out.endTag(null, TAG_URI_GRANT);
7737            }
7738            out.endTag(null, TAG_URI_GRANTS);
7739            out.endDocument();
7740
7741            mGrantFile.finishWrite(fos);
7742        } catch (IOException e) {
7743            if (fos != null) {
7744                mGrantFile.failWrite(fos);
7745            }
7746        }
7747    }
7748
7749    private void readGrantedUriPermissionsLocked() {
7750        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7751
7752        final long now = System.currentTimeMillis();
7753
7754        FileInputStream fis = null;
7755        try {
7756            fis = mGrantFile.openRead();
7757            final XmlPullParser in = Xml.newPullParser();
7758            in.setInput(fis, null);
7759
7760            int type;
7761            while ((type = in.next()) != END_DOCUMENT) {
7762                final String tag = in.getName();
7763                if (type == START_TAG) {
7764                    if (TAG_URI_GRANT.equals(tag)) {
7765                        final int sourceUserId;
7766                        final int targetUserId;
7767                        final int userHandle = readIntAttribute(in,
7768                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7769                        if (userHandle != UserHandle.USER_NULL) {
7770                            // For backwards compatibility.
7771                            sourceUserId = userHandle;
7772                            targetUserId = userHandle;
7773                        } else {
7774                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7775                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7776                        }
7777                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7778                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7779                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7780                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7781                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7782                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7783
7784                        // Sanity check that provider still belongs to source package
7785                        final ProviderInfo pi = getProviderInfoLocked(
7786                                uri.getAuthority(), sourceUserId);
7787                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7788                            int targetUid = -1;
7789                            try {
7790                                targetUid = AppGlobals.getPackageManager()
7791                                        .getPackageUid(targetPkg, targetUserId);
7792                            } catch (RemoteException e) {
7793                            }
7794                            if (targetUid != -1) {
7795                                final UriPermission perm = findOrCreateUriPermissionLocked(
7796                                        sourcePkg, targetPkg, targetUid,
7797                                        new GrantUri(sourceUserId, uri, prefix));
7798                                perm.initPersistedModes(modeFlags, createdTime);
7799                            }
7800                        } else {
7801                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7802                                    + " but instead found " + pi);
7803                        }
7804                    }
7805                }
7806            }
7807        } catch (FileNotFoundException e) {
7808            // Missing grants is okay
7809        } catch (IOException e) {
7810            Slog.wtf(TAG, "Failed reading Uri grants", e);
7811        } catch (XmlPullParserException e) {
7812            Slog.wtf(TAG, "Failed reading Uri grants", e);
7813        } finally {
7814            IoUtils.closeQuietly(fis);
7815        }
7816    }
7817
7818    /**
7819     * @param uri This uri must NOT contain an embedded userId.
7820     * @param userId The userId in which the uri is to be resolved.
7821     */
7822    @Override
7823    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7824        enforceNotIsolatedCaller("takePersistableUriPermission");
7825
7826        Preconditions.checkFlagsArgument(modeFlags,
7827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7828
7829        synchronized (this) {
7830            final int callingUid = Binder.getCallingUid();
7831            boolean persistChanged = false;
7832            GrantUri grantUri = new GrantUri(userId, uri, false);
7833
7834            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7835                    new GrantUri(userId, uri, false));
7836            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7837                    new GrantUri(userId, uri, true));
7838
7839            final boolean exactValid = (exactPerm != null)
7840                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7841            final boolean prefixValid = (prefixPerm != null)
7842                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7843
7844            if (!(exactValid || prefixValid)) {
7845                throw new SecurityException("No persistable permission grants found for UID "
7846                        + callingUid + " and Uri " + grantUri.toSafeString());
7847            }
7848
7849            if (exactValid) {
7850                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7851            }
7852            if (prefixValid) {
7853                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7854            }
7855
7856            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7857
7858            if (persistChanged) {
7859                schedulePersistUriGrants();
7860            }
7861        }
7862    }
7863
7864    /**
7865     * @param uri This uri must NOT contain an embedded userId.
7866     * @param userId The userId in which the uri is to be resolved.
7867     */
7868    @Override
7869    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7870        enforceNotIsolatedCaller("releasePersistableUriPermission");
7871
7872        Preconditions.checkFlagsArgument(modeFlags,
7873                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7874
7875        synchronized (this) {
7876            final int callingUid = Binder.getCallingUid();
7877            boolean persistChanged = false;
7878
7879            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7880                    new GrantUri(userId, uri, false));
7881            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7882                    new GrantUri(userId, uri, true));
7883            if (exactPerm == null && prefixPerm == null) {
7884                throw new SecurityException("No permission grants found for UID " + callingUid
7885                        + " and Uri " + uri.toSafeString());
7886            }
7887
7888            if (exactPerm != null) {
7889                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7890                removeUriPermissionIfNeededLocked(exactPerm);
7891            }
7892            if (prefixPerm != null) {
7893                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7894                removeUriPermissionIfNeededLocked(prefixPerm);
7895            }
7896
7897            if (persistChanged) {
7898                schedulePersistUriGrants();
7899            }
7900        }
7901    }
7902
7903    /**
7904     * Prune any older {@link UriPermission} for the given UID until outstanding
7905     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7906     *
7907     * @return if any mutations occured that require persisting.
7908     */
7909    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7910        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7911        if (perms == null) return false;
7912        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7913
7914        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7915        for (UriPermission perm : perms.values()) {
7916            if (perm.persistedModeFlags != 0) {
7917                persisted.add(perm);
7918            }
7919        }
7920
7921        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7922        if (trimCount <= 0) return false;
7923
7924        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7925        for (int i = 0; i < trimCount; i++) {
7926            final UriPermission perm = persisted.get(i);
7927
7928            if (DEBUG_URI_PERMISSION) {
7929                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7930            }
7931
7932            perm.releasePersistableModes(~0);
7933            removeUriPermissionIfNeededLocked(perm);
7934        }
7935
7936        return true;
7937    }
7938
7939    @Override
7940    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7941            String packageName, boolean incoming) {
7942        enforceNotIsolatedCaller("getPersistedUriPermissions");
7943        Preconditions.checkNotNull(packageName, "packageName");
7944
7945        final int callingUid = Binder.getCallingUid();
7946        final IPackageManager pm = AppGlobals.getPackageManager();
7947        try {
7948            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7949            if (packageUid != callingUid) {
7950                throw new SecurityException(
7951                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7952            }
7953        } catch (RemoteException e) {
7954            throw new SecurityException("Failed to verify package name ownership");
7955        }
7956
7957        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7958        synchronized (this) {
7959            if (incoming) {
7960                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7961                        callingUid);
7962                if (perms == null) {
7963                    Slog.w(TAG, "No permission grants found for " + packageName);
7964                } else {
7965                    for (UriPermission perm : perms.values()) {
7966                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7967                            result.add(perm.buildPersistedPublicApiObject());
7968                        }
7969                    }
7970                }
7971            } else {
7972                final int size = mGrantedUriPermissions.size();
7973                for (int i = 0; i < size; i++) {
7974                    final ArrayMap<GrantUri, UriPermission> perms =
7975                            mGrantedUriPermissions.valueAt(i);
7976                    for (UriPermission perm : perms.values()) {
7977                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7978                            result.add(perm.buildPersistedPublicApiObject());
7979                        }
7980                    }
7981                }
7982            }
7983        }
7984        return new ParceledListSlice<android.content.UriPermission>(result);
7985    }
7986
7987    @Override
7988    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7989        synchronized (this) {
7990            ProcessRecord app =
7991                who != null ? getRecordForAppLocked(who) : null;
7992            if (app == null) return;
7993
7994            Message msg = Message.obtain();
7995            msg.what = WAIT_FOR_DEBUGGER_MSG;
7996            msg.obj = app;
7997            msg.arg1 = waiting ? 1 : 0;
7998            mHandler.sendMessage(msg);
7999        }
8000    }
8001
8002    @Override
8003    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8004        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8005        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8006        outInfo.availMem = Process.getFreeMemory();
8007        outInfo.totalMem = Process.getTotalMemory();
8008        outInfo.threshold = homeAppMem;
8009        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8010        outInfo.hiddenAppThreshold = cachedAppMem;
8011        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8012                ProcessList.SERVICE_ADJ);
8013        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8014                ProcessList.VISIBLE_APP_ADJ);
8015        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8016                ProcessList.FOREGROUND_APP_ADJ);
8017    }
8018
8019    // =========================================================
8020    // TASK MANAGEMENT
8021    // =========================================================
8022
8023    @Override
8024    public List<IAppTask> getAppTasks(String callingPackage) {
8025        int callingUid = Binder.getCallingUid();
8026        long ident = Binder.clearCallingIdentity();
8027
8028        synchronized(this) {
8029            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8030            try {
8031                if (localLOGV) Slog.v(TAG, "getAppTasks");
8032
8033                final int N = mRecentTasks.size();
8034                for (int i = 0; i < N; i++) {
8035                    TaskRecord tr = mRecentTasks.get(i);
8036                    // Skip tasks that do not match the caller.  We don't need to verify
8037                    // callingPackage, because we are also limiting to callingUid and know
8038                    // that will limit to the correct security sandbox.
8039                    if (tr.effectiveUid != callingUid) {
8040                        continue;
8041                    }
8042                    Intent intent = tr.getBaseIntent();
8043                    if (intent == null ||
8044                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8045                        continue;
8046                    }
8047                    ActivityManager.RecentTaskInfo taskInfo =
8048                            createRecentTaskInfoFromTaskRecord(tr);
8049                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8050                    list.add(taskImpl);
8051                }
8052            } finally {
8053                Binder.restoreCallingIdentity(ident);
8054            }
8055            return list;
8056        }
8057    }
8058
8059    @Override
8060    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8061        final int callingUid = Binder.getCallingUid();
8062        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8063
8064        synchronized(this) {
8065            if (localLOGV) Slog.v(
8066                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8067
8068            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8069                    callingUid);
8070
8071            // TODO: Improve with MRU list from all ActivityStacks.
8072            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8073        }
8074
8075        return list;
8076    }
8077
8078    /**
8079     * Creates a new RecentTaskInfo from a TaskRecord.
8080     */
8081    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8082        // Update the task description to reflect any changes in the task stack
8083        tr.updateTaskDescription();
8084
8085        // Compose the recent task info
8086        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8087        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8088        rti.persistentId = tr.taskId;
8089        rti.baseIntent = new Intent(tr.getBaseIntent());
8090        rti.origActivity = tr.origActivity;
8091        rti.description = tr.lastDescription;
8092        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8093        rti.userId = tr.userId;
8094        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8095        rti.firstActiveTime = tr.firstActiveTime;
8096        rti.lastActiveTime = tr.lastActiveTime;
8097        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8098        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8099        return rti;
8100    }
8101
8102    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8103        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8104                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8105        if (!allowed) {
8106            if (checkPermission(android.Manifest.permission.GET_TASKS,
8107                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8108                // Temporary compatibility: some existing apps on the system image may
8109                // still be requesting the old permission and not switched to the new
8110                // one; if so, we'll still allow them full access.  This means we need
8111                // to see if they are holding the old permission and are a system app.
8112                try {
8113                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8114                        allowed = true;
8115                        Slog.w(TAG, caller + ": caller " + callingUid
8116                                + " is using old GET_TASKS but privileged; allowing");
8117                    }
8118                } catch (RemoteException e) {
8119                }
8120            }
8121        }
8122        if (!allowed) {
8123            Slog.w(TAG, caller + ": caller " + callingUid
8124                    + " does not hold GET_TASKS; limiting output");
8125        }
8126        return allowed;
8127    }
8128
8129    @Override
8130    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8131        final int callingUid = Binder.getCallingUid();
8132        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8133                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8134
8135        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8136        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8137        synchronized (this) {
8138            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8139                    callingUid);
8140            final boolean detailed = checkCallingPermission(
8141                    android.Manifest.permission.GET_DETAILED_TASKS)
8142                    == PackageManager.PERMISSION_GRANTED;
8143
8144            final int N = mRecentTasks.size();
8145            ArrayList<ActivityManager.RecentTaskInfo> res
8146                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8147                            maxNum < N ? maxNum : N);
8148
8149            final Set<Integer> includedUsers;
8150            if (includeProfiles) {
8151                includedUsers = getProfileIdsLocked(userId);
8152            } else {
8153                includedUsers = new HashSet<Integer>();
8154            }
8155            includedUsers.add(Integer.valueOf(userId));
8156
8157            for (int i=0; i<N && maxNum > 0; i++) {
8158                TaskRecord tr = mRecentTasks.get(i);
8159                // Only add calling user or related users recent tasks
8160                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8161                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8162                    continue;
8163                }
8164
8165                // Return the entry if desired by the caller.  We always return
8166                // the first entry, because callers always expect this to be the
8167                // foreground app.  We may filter others if the caller has
8168                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8169                // we should exclude the entry.
8170
8171                if (i == 0
8172                        || withExcluded
8173                        || (tr.intent == null)
8174                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8175                                == 0)) {
8176                    if (!allowed) {
8177                        // If the caller doesn't have the GET_TASKS permission, then only
8178                        // allow them to see a small subset of tasks -- their own and home.
8179                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8180                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8181                            continue;
8182                        }
8183                    }
8184                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8185                        if (tr.stack != null && tr.stack.isHomeStack()) {
8186                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8187                            continue;
8188                        }
8189                    }
8190                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8191                        // Don't include auto remove tasks that are finished or finishing.
8192                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8193                                + tr);
8194                        continue;
8195                    }
8196                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8197                            && !tr.isAvailable) {
8198                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8199                        continue;
8200                    }
8201
8202                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8203                    if (!detailed) {
8204                        rti.baseIntent.replaceExtras((Bundle)null);
8205                    }
8206
8207                    res.add(rti);
8208                    maxNum--;
8209                }
8210            }
8211            return res;
8212        }
8213    }
8214
8215    TaskRecord recentTaskForIdLocked(int id) {
8216        final int N = mRecentTasks.size();
8217            for (int i=0; i<N; i++) {
8218                TaskRecord tr = mRecentTasks.get(i);
8219                if (tr.taskId == id) {
8220                    return tr;
8221                }
8222            }
8223            return null;
8224    }
8225
8226    @Override
8227    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8228        synchronized (this) {
8229            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8230                    "getTaskThumbnail()");
8231            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8232            if (tr != null) {
8233                return tr.getTaskThumbnailLocked();
8234            }
8235        }
8236        return null;
8237    }
8238
8239    @Override
8240    public int addAppTask(IBinder activityToken, Intent intent,
8241            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8242        final int callingUid = Binder.getCallingUid();
8243        final long callingIdent = Binder.clearCallingIdentity();
8244
8245        try {
8246            synchronized (this) {
8247                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8248                if (r == null) {
8249                    throw new IllegalArgumentException("Activity does not exist; token="
8250                            + activityToken);
8251                }
8252                ComponentName comp = intent.getComponent();
8253                if (comp == null) {
8254                    throw new IllegalArgumentException("Intent " + intent
8255                            + " must specify explicit component");
8256                }
8257                if (thumbnail.getWidth() != mThumbnailWidth
8258                        || thumbnail.getHeight() != mThumbnailHeight) {
8259                    throw new IllegalArgumentException("Bad thumbnail size: got "
8260                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8261                            + mThumbnailWidth + "x" + mThumbnailHeight);
8262                }
8263                if (intent.getSelector() != null) {
8264                    intent.setSelector(null);
8265                }
8266                if (intent.getSourceBounds() != null) {
8267                    intent.setSourceBounds(null);
8268                }
8269                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8270                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8271                        // The caller has added this as an auto-remove task...  that makes no
8272                        // sense, so turn off auto-remove.
8273                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8274                    }
8275                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8276                    // Must be a new task.
8277                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8278                }
8279                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8280                    mLastAddedTaskActivity = null;
8281                }
8282                ActivityInfo ainfo = mLastAddedTaskActivity;
8283                if (ainfo == null) {
8284                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8285                            comp, 0, UserHandle.getUserId(callingUid));
8286                    if (ainfo.applicationInfo.uid != callingUid) {
8287                        throw new SecurityException(
8288                                "Can't add task for another application: target uid="
8289                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8290                    }
8291                }
8292
8293                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8294                        intent, description);
8295
8296                int trimIdx = trimRecentsForTaskLocked(task, false);
8297                if (trimIdx >= 0) {
8298                    // If this would have caused a trim, then we'll abort because that
8299                    // means it would be added at the end of the list but then just removed.
8300                    return INVALID_TASK_ID;
8301                }
8302
8303                final int N = mRecentTasks.size();
8304                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8305                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8306                    tr.removedFromRecents();
8307                }
8308
8309                task.inRecents = true;
8310                mRecentTasks.add(task);
8311                r.task.stack.addTask(task, false, false);
8312
8313                task.setLastThumbnail(thumbnail);
8314                task.freeLastThumbnail();
8315
8316                return task.taskId;
8317            }
8318        } finally {
8319            Binder.restoreCallingIdentity(callingIdent);
8320        }
8321    }
8322
8323    @Override
8324    public Point getAppTaskThumbnailSize() {
8325        synchronized (this) {
8326            return new Point(mThumbnailWidth,  mThumbnailHeight);
8327        }
8328    }
8329
8330    @Override
8331    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8332        synchronized (this) {
8333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8334            if (r != null) {
8335                r.setTaskDescription(td);
8336                r.task.updateTaskDescription();
8337            }
8338        }
8339    }
8340
8341    @Override
8342    public Bitmap getTaskDescriptionIcon(String filename) {
8343        if (!FileUtils.isValidExtFilename(filename)
8344                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8345            throw new IllegalArgumentException("Bad filename: " + filename);
8346        }
8347        return mTaskPersister.getTaskDescriptionIcon(filename);
8348    }
8349
8350    @Override
8351    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8352            throws RemoteException {
8353        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8354                opts.getCustomInPlaceResId() == 0) {
8355            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8356                    "with valid animation");
8357        }
8358        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8359        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8360                opts.getCustomInPlaceResId());
8361        mWindowManager.executeAppTransition();
8362    }
8363
8364    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8365        mRecentTasks.remove(tr);
8366        tr.removedFromRecents();
8367        ComponentName component = tr.getBaseIntent().getComponent();
8368        if (component == null) {
8369            Slog.w(TAG, "No component for base intent of task: " + tr);
8370            return;
8371        }
8372
8373        if (!killProcess) {
8374            return;
8375        }
8376
8377        // Determine if the process(es) for this task should be killed.
8378        final String pkg = component.getPackageName();
8379        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8380        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8381        for (int i = 0; i < pmap.size(); i++) {
8382
8383            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8384            for (int j = 0; j < uids.size(); j++) {
8385                ProcessRecord proc = uids.valueAt(j);
8386                if (proc.userId != tr.userId) {
8387                    // Don't kill process for a different user.
8388                    continue;
8389                }
8390                if (proc == mHomeProcess) {
8391                    // Don't kill the home process along with tasks from the same package.
8392                    continue;
8393                }
8394                if (!proc.pkgList.containsKey(pkg)) {
8395                    // Don't kill process that is not associated with this task.
8396                    continue;
8397                }
8398
8399                for (int k = 0; k < proc.activities.size(); k++) {
8400                    TaskRecord otherTask = proc.activities.get(k).task;
8401                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8402                        // Don't kill process(es) that has an activity in a different task that is
8403                        // also in recents.
8404                        return;
8405                    }
8406                }
8407
8408                // Add process to kill list.
8409                procsToKill.add(proc);
8410            }
8411        }
8412
8413        // Find any running services associated with this app and stop if needed.
8414        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8415
8416        // Kill the running processes.
8417        for (int i = 0; i < procsToKill.size(); i++) {
8418            ProcessRecord pr = procsToKill.get(i);
8419            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8420                pr.kill("remove task", true);
8421            } else {
8422                pr.waitingToKill = "remove task";
8423            }
8424        }
8425    }
8426
8427    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8428        // Remove all tasks with activities in the specified package from the list of recent tasks
8429        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8430            TaskRecord tr = mRecentTasks.get(i);
8431            if (tr.userId != userId) continue;
8432
8433            ComponentName cn = tr.intent.getComponent();
8434            if (cn != null && cn.getPackageName().equals(packageName)) {
8435                // If the package name matches, remove the task.
8436                removeTaskByIdLocked(tr.taskId, true);
8437            }
8438        }
8439    }
8440
8441    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8442        final IPackageManager pm = AppGlobals.getPackageManager();
8443        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8444
8445        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8446            TaskRecord tr = mRecentTasks.get(i);
8447            if (tr.userId != userId) continue;
8448
8449            ComponentName cn = tr.intent.getComponent();
8450            if (cn != null && cn.getPackageName().equals(packageName)) {
8451                // Skip if component still exists in the package.
8452                if (componentsKnownToExist.contains(cn)) continue;
8453
8454                try {
8455                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8456                    if (info != null) {
8457                        componentsKnownToExist.add(cn);
8458                    } else {
8459                        removeTaskByIdLocked(tr.taskId, false);
8460                    }
8461                } catch (RemoteException e) {
8462                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8463                }
8464            }
8465        }
8466    }
8467
8468    /**
8469     * Removes the task with the specified task id.
8470     *
8471     * @param taskId Identifier of the task to be removed.
8472     * @param killProcess Kill any process associated with the task if possible.
8473     * @return Returns true if the given task was found and removed.
8474     */
8475    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8476        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8477        if (tr != null) {
8478            tr.removeTaskActivitiesLocked();
8479            cleanUpRemovedTaskLocked(tr, killProcess);
8480            if (tr.isPersistable) {
8481                notifyTaskPersisterLocked(null, true);
8482            }
8483            return true;
8484        }
8485        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8486        return false;
8487    }
8488
8489    @Override
8490    public boolean removeTask(int taskId) {
8491        synchronized (this) {
8492            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8493                    "removeTask()");
8494            long ident = Binder.clearCallingIdentity();
8495            try {
8496                return removeTaskByIdLocked(taskId, true);
8497            } finally {
8498                Binder.restoreCallingIdentity(ident);
8499            }
8500        }
8501    }
8502
8503    /**
8504     * TODO: Add mController hook
8505     */
8506    @Override
8507    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8508        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8509                "moveTaskToFront()");
8510
8511        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8512        synchronized(this) {
8513            moveTaskToFrontLocked(taskId, flags, options);
8514        }
8515    }
8516
8517    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8518        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8519                Binder.getCallingUid(), -1, -1, "Task to front")) {
8520            ActivityOptions.abort(options);
8521            return;
8522        }
8523        final long origId = Binder.clearCallingIdentity();
8524        try {
8525            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8526            if (task == null) {
8527                Slog.d(TAG, "Could not find task for id: "+ taskId);
8528                return;
8529            }
8530            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8531                mStackSupervisor.showLockTaskToast();
8532                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8533                return;
8534            }
8535            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8536            if (prev != null && prev.isRecentsActivity()) {
8537                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8538            }
8539            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8540        } finally {
8541            Binder.restoreCallingIdentity(origId);
8542        }
8543        ActivityOptions.abort(options);
8544    }
8545
8546    @Override
8547    public void moveTaskToBack(int taskId) {
8548        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8549                "moveTaskToBack()");
8550
8551        synchronized(this) {
8552            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8553            if (tr != null) {
8554                if (tr == mStackSupervisor.mLockTaskModeTask) {
8555                    mStackSupervisor.showLockTaskToast();
8556                    return;
8557                }
8558                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8559                ActivityStack stack = tr.stack;
8560                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8561                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8562                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8563                        return;
8564                    }
8565                }
8566                final long origId = Binder.clearCallingIdentity();
8567                try {
8568                    stack.moveTaskToBackLocked(taskId, null);
8569                } finally {
8570                    Binder.restoreCallingIdentity(origId);
8571                }
8572            }
8573        }
8574    }
8575
8576    /**
8577     * Moves an activity, and all of the other activities within the same task, to the bottom
8578     * of the history stack.  The activity's order within the task is unchanged.
8579     *
8580     * @param token A reference to the activity we wish to move
8581     * @param nonRoot If false then this only works if the activity is the root
8582     *                of a task; if true it will work for any activity in a task.
8583     * @return Returns true if the move completed, false if not.
8584     */
8585    @Override
8586    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8587        enforceNotIsolatedCaller("moveActivityTaskToBack");
8588        synchronized(this) {
8589            final long origId = Binder.clearCallingIdentity();
8590            try {
8591                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8592                if (taskId >= 0) {
8593                    if ((mStackSupervisor.mLockTaskModeTask != null)
8594                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8595                        mStackSupervisor.showLockTaskToast();
8596                        return false;
8597                    }
8598                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8599                }
8600            } finally {
8601                Binder.restoreCallingIdentity(origId);
8602            }
8603        }
8604        return false;
8605    }
8606
8607    @Override
8608    public void moveTaskBackwards(int task) {
8609        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8610                "moveTaskBackwards()");
8611
8612        synchronized(this) {
8613            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8614                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8615                return;
8616            }
8617            final long origId = Binder.clearCallingIdentity();
8618            moveTaskBackwardsLocked(task);
8619            Binder.restoreCallingIdentity(origId);
8620        }
8621    }
8622
8623    private final void moveTaskBackwardsLocked(int task) {
8624        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8625    }
8626
8627    @Override
8628    public IBinder getHomeActivityToken() throws RemoteException {
8629        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8630                "getHomeActivityToken()");
8631        synchronized (this) {
8632            return mStackSupervisor.getHomeActivityToken();
8633        }
8634    }
8635
8636    @Override
8637    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8638            IActivityContainerCallback callback) throws RemoteException {
8639        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8640                "createActivityContainer()");
8641        synchronized (this) {
8642            if (parentActivityToken == null) {
8643                throw new IllegalArgumentException("parent token must not be null");
8644            }
8645            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8646            if (r == null) {
8647                return null;
8648            }
8649            if (callback == null) {
8650                throw new IllegalArgumentException("callback must not be null");
8651            }
8652            return mStackSupervisor.createActivityContainer(r, callback);
8653        }
8654    }
8655
8656    @Override
8657    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "deleteActivityContainer()");
8660        synchronized (this) {
8661            mStackSupervisor.deleteActivityContainer(container);
8662        }
8663    }
8664
8665    @Override
8666    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8667            throws RemoteException {
8668        synchronized (this) {
8669            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8670            if (stack != null) {
8671                return stack.mActivityContainer;
8672            }
8673            return null;
8674        }
8675    }
8676
8677    @Override
8678    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8679        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8680                "moveTaskToStack()");
8681        if (stackId == HOME_STACK_ID) {
8682            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8683                    new RuntimeException("here").fillInStackTrace());
8684        }
8685        synchronized (this) {
8686            long ident = Binder.clearCallingIdentity();
8687            try {
8688                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8689                        + stackId + " toTop=" + toTop);
8690                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8691            } finally {
8692                Binder.restoreCallingIdentity(ident);
8693            }
8694        }
8695    }
8696
8697    @Override
8698    public void resizeStack(int stackBoxId, Rect bounds) {
8699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8700                "resizeStackBox()");
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            mWindowManager.resizeStack(stackBoxId, bounds);
8704        } finally {
8705            Binder.restoreCallingIdentity(ident);
8706        }
8707    }
8708
8709    @Override
8710    public List<StackInfo> getAllStackInfos() {
8711        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8712                "getAllStackInfos()");
8713        long ident = Binder.clearCallingIdentity();
8714        try {
8715            synchronized (this) {
8716                return mStackSupervisor.getAllStackInfosLocked();
8717            }
8718        } finally {
8719            Binder.restoreCallingIdentity(ident);
8720        }
8721    }
8722
8723    @Override
8724    public StackInfo getStackInfo(int stackId) {
8725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8726                "getStackInfo()");
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            synchronized (this) {
8730                return mStackSupervisor.getStackInfoLocked(stackId);
8731            }
8732        } finally {
8733            Binder.restoreCallingIdentity(ident);
8734        }
8735    }
8736
8737    @Override
8738    public boolean isInHomeStack(int taskId) {
8739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8740                "getStackInfo()");
8741        long ident = Binder.clearCallingIdentity();
8742        try {
8743            synchronized (this) {
8744                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8745                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8746            }
8747        } finally {
8748            Binder.restoreCallingIdentity(ident);
8749        }
8750    }
8751
8752    @Override
8753    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8754        synchronized(this) {
8755            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8756        }
8757    }
8758
8759    private boolean isLockTaskAuthorized(String pkg) {
8760        final DevicePolicyManager dpm = (DevicePolicyManager)
8761                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8762        try {
8763            int uid = mContext.getPackageManager().getPackageUid(pkg,
8764                    Binder.getCallingUserHandle().getIdentifier());
8765            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8766        } catch (NameNotFoundException e) {
8767            return false;
8768        }
8769    }
8770
8771    void startLockTaskMode(TaskRecord task) {
8772        final String pkg;
8773        synchronized (this) {
8774            pkg = task.intent.getComponent().getPackageName();
8775        }
8776        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8777        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8778            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8779                    StatusBarManagerInternal.class);
8780            if (statusBarManager != null) {
8781                statusBarManager.showScreenPinningRequest();
8782            }
8783            return;
8784        }
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                // Since we lost lock on task, make sure it is still there.
8789                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8790                if (task != null) {
8791                    if (!isSystemInitiated
8792                            && ((mStackSupervisor.getFocusedStack() == null)
8793                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8794                        throw new IllegalArgumentException("Invalid task, not in foreground");
8795                    }
8796                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8797                }
8798            }
8799        } finally {
8800            Binder.restoreCallingIdentity(ident);
8801        }
8802    }
8803
8804    @Override
8805    public void startLockTaskMode(int taskId) {
8806        final TaskRecord task;
8807        long ident = Binder.clearCallingIdentity();
8808        try {
8809            synchronized (this) {
8810                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8811            }
8812        } finally {
8813            Binder.restoreCallingIdentity(ident);
8814        }
8815        if (task != null) {
8816            startLockTaskMode(task);
8817        }
8818    }
8819
8820    @Override
8821    public void startLockTaskMode(IBinder token) {
8822        final TaskRecord task;
8823        long ident = Binder.clearCallingIdentity();
8824        try {
8825            synchronized (this) {
8826                final ActivityRecord r = ActivityRecord.forToken(token);
8827                if (r == null) {
8828                    return;
8829                }
8830                task = r.task;
8831            }
8832        } finally {
8833            Binder.restoreCallingIdentity(ident);
8834        }
8835        if (task != null) {
8836            startLockTaskMode(task);
8837        }
8838    }
8839
8840    @Override
8841    public void startLockTaskModeOnCurrent() throws RemoteException {
8842        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8843                "startLockTaskModeOnCurrent");
8844        long ident = Binder.clearCallingIdentity();
8845        try {
8846            ActivityRecord r = null;
8847            synchronized (this) {
8848                r = mStackSupervisor.topRunningActivityLocked();
8849            }
8850            startLockTaskMode(r.task);
8851        } finally {
8852            Binder.restoreCallingIdentity(ident);
8853        }
8854    }
8855
8856    @Override
8857    public void stopLockTaskMode() {
8858        // Verify that the user matches the package of the intent for the TaskRecord
8859        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8860        // and stopLockTaskMode.
8861        final int callingUid = Binder.getCallingUid();
8862        if (callingUid != Process.SYSTEM_UID) {
8863            try {
8864                String pkg =
8865                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8866                int uid = mContext.getPackageManager().getPackageUid(pkg,
8867                        Binder.getCallingUserHandle().getIdentifier());
8868                if (uid != callingUid) {
8869                    throw new SecurityException("Invalid uid, expected " + uid);
8870                }
8871            } catch (NameNotFoundException e) {
8872                Log.d(TAG, "stopLockTaskMode " + e);
8873                return;
8874            }
8875        }
8876        long ident = Binder.clearCallingIdentity();
8877        try {
8878            Log.d(TAG, "stopLockTaskMode");
8879            // Stop lock task
8880            synchronized (this) {
8881                mStackSupervisor.setLockTaskModeLocked(null, false);
8882            }
8883        } finally {
8884            Binder.restoreCallingIdentity(ident);
8885        }
8886    }
8887
8888    @Override
8889    public void stopLockTaskModeOnCurrent() throws RemoteException {
8890        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8891                "stopLockTaskModeOnCurrent");
8892        long ident = Binder.clearCallingIdentity();
8893        try {
8894            stopLockTaskMode();
8895        } finally {
8896            Binder.restoreCallingIdentity(ident);
8897        }
8898    }
8899
8900    @Override
8901    public boolean isInLockTaskMode() {
8902        synchronized (this) {
8903            return mStackSupervisor.isInLockTaskMode();
8904        }
8905    }
8906
8907    // =========================================================
8908    // CONTENT PROVIDERS
8909    // =========================================================
8910
8911    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8912        List<ProviderInfo> providers = null;
8913        try {
8914            providers = AppGlobals.getPackageManager().
8915                queryContentProviders(app.processName, app.uid,
8916                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8917        } catch (RemoteException ex) {
8918        }
8919        if (DEBUG_MU)
8920            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8921        int userId = app.userId;
8922        if (providers != null) {
8923            int N = providers.size();
8924            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8925            for (int i=0; i<N; i++) {
8926                ProviderInfo cpi =
8927                    (ProviderInfo)providers.get(i);
8928                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8929                        cpi.name, cpi.flags);
8930                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8931                    // This is a singleton provider, but a user besides the
8932                    // default user is asking to initialize a process it runs
8933                    // in...  well, no, it doesn't actually run in this process,
8934                    // it runs in the process of the default user.  Get rid of it.
8935                    providers.remove(i);
8936                    N--;
8937                    i--;
8938                    continue;
8939                }
8940
8941                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8942                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8943                if (cpr == null) {
8944                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8945                    mProviderMap.putProviderByClass(comp, cpr);
8946                }
8947                if (DEBUG_MU)
8948                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8949                app.pubProviders.put(cpi.name, cpr);
8950                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8951                    // Don't add this if it is a platform component that is marked
8952                    // to run in multiple processes, because this is actually
8953                    // part of the framework so doesn't make sense to track as a
8954                    // separate apk in the process.
8955                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8956                            mProcessStats);
8957                }
8958                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8959            }
8960        }
8961        return providers;
8962    }
8963
8964    /**
8965     * Check if {@link ProcessRecord} has a possible chance at accessing the
8966     * given {@link ProviderInfo}. Final permission checking is always done
8967     * in {@link ContentProvider}.
8968     */
8969    private final String checkContentProviderPermissionLocked(
8970            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8971        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8972        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8973        boolean checkedGrants = false;
8974        if (checkUser) {
8975            // Looking for cross-user grants before enforcing the typical cross-users permissions
8976            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8977            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8978                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8979                    return null;
8980                }
8981                checkedGrants = true;
8982            }
8983            userId = handleIncomingUser(callingPid, callingUid, userId,
8984                    false, ALLOW_NON_FULL,
8985                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8986            if (userId != tmpTargetUserId) {
8987                // When we actually went to determine the final targer user ID, this ended
8988                // up different than our initial check for the authority.  This is because
8989                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8990                // SELF.  So we need to re-check the grants again.
8991                checkedGrants = false;
8992            }
8993        }
8994        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8995                cpi.applicationInfo.uid, cpi.exported)
8996                == PackageManager.PERMISSION_GRANTED) {
8997            return null;
8998        }
8999        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9000                cpi.applicationInfo.uid, cpi.exported)
9001                == PackageManager.PERMISSION_GRANTED) {
9002            return null;
9003        }
9004
9005        PathPermission[] pps = cpi.pathPermissions;
9006        if (pps != null) {
9007            int i = pps.length;
9008            while (i > 0) {
9009                i--;
9010                PathPermission pp = pps[i];
9011                String pprperm = pp.getReadPermission();
9012                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9013                        cpi.applicationInfo.uid, cpi.exported)
9014                        == PackageManager.PERMISSION_GRANTED) {
9015                    return null;
9016                }
9017                String ppwperm = pp.getWritePermission();
9018                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9019                        cpi.applicationInfo.uid, cpi.exported)
9020                        == PackageManager.PERMISSION_GRANTED) {
9021                    return null;
9022                }
9023            }
9024        }
9025        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9026            return null;
9027        }
9028
9029        String msg;
9030        if (!cpi.exported) {
9031            msg = "Permission Denial: opening provider " + cpi.name
9032                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9033                    + ", uid=" + callingUid + ") that is not exported from uid "
9034                    + cpi.applicationInfo.uid;
9035        } else {
9036            msg = "Permission Denial: opening provider " + cpi.name
9037                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9038                    + ", uid=" + callingUid + ") requires "
9039                    + cpi.readPermission + " or " + cpi.writePermission;
9040        }
9041        Slog.w(TAG, msg);
9042        return msg;
9043    }
9044
9045    /**
9046     * Returns if the ContentProvider has granted a uri to callingUid
9047     */
9048    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9049        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9050        if (perms != null) {
9051            for (int i=perms.size()-1; i>=0; i--) {
9052                GrantUri grantUri = perms.keyAt(i);
9053                if (grantUri.sourceUserId == userId || !checkUser) {
9054                    if (matchesProvider(grantUri.uri, cpi)) {
9055                        return true;
9056                    }
9057                }
9058            }
9059        }
9060        return false;
9061    }
9062
9063    /**
9064     * Returns true if the uri authority is one of the authorities specified in the provider.
9065     */
9066    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9067        String uriAuth = uri.getAuthority();
9068        String cpiAuth = cpi.authority;
9069        if (cpiAuth.indexOf(';') == -1) {
9070            return cpiAuth.equals(uriAuth);
9071        }
9072        String[] cpiAuths = cpiAuth.split(";");
9073        int length = cpiAuths.length;
9074        for (int i = 0; i < length; i++) {
9075            if (cpiAuths[i].equals(uriAuth)) return true;
9076        }
9077        return false;
9078    }
9079
9080    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9081            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9082        if (r != null) {
9083            for (int i=0; i<r.conProviders.size(); i++) {
9084                ContentProviderConnection conn = r.conProviders.get(i);
9085                if (conn.provider == cpr) {
9086                    if (DEBUG_PROVIDER) Slog.v(TAG,
9087                            "Adding provider requested by "
9088                            + r.processName + " from process "
9089                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9090                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9091                    if (stable) {
9092                        conn.stableCount++;
9093                        conn.numStableIncs++;
9094                    } else {
9095                        conn.unstableCount++;
9096                        conn.numUnstableIncs++;
9097                    }
9098                    return conn;
9099                }
9100            }
9101            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9102            if (stable) {
9103                conn.stableCount = 1;
9104                conn.numStableIncs = 1;
9105            } else {
9106                conn.unstableCount = 1;
9107                conn.numUnstableIncs = 1;
9108            }
9109            cpr.connections.add(conn);
9110            r.conProviders.add(conn);
9111            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9112            return conn;
9113        }
9114        cpr.addExternalProcessHandleLocked(externalProcessToken);
9115        return null;
9116    }
9117
9118    boolean decProviderCountLocked(ContentProviderConnection conn,
9119            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9120        if (conn != null) {
9121            cpr = conn.provider;
9122            if (DEBUG_PROVIDER) Slog.v(TAG,
9123                    "Removing provider requested by "
9124                    + conn.client.processName + " from process "
9125                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9126                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9127            if (stable) {
9128                conn.stableCount--;
9129            } else {
9130                conn.unstableCount--;
9131            }
9132            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9133                cpr.connections.remove(conn);
9134                conn.client.conProviders.remove(conn);
9135                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9136                return true;
9137            }
9138            return false;
9139        }
9140        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9141        return false;
9142    }
9143
9144    private void checkTime(long startTime, String where) {
9145        long now = SystemClock.elapsedRealtime();
9146        if ((now-startTime) > 1000) {
9147            // If we are taking more than a second, log about it.
9148            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9149        }
9150    }
9151
9152    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9153            String name, IBinder token, boolean stable, int userId) {
9154        ContentProviderRecord cpr;
9155        ContentProviderConnection conn = null;
9156        ProviderInfo cpi = null;
9157
9158        synchronized(this) {
9159            long startTime = SystemClock.elapsedRealtime();
9160
9161            ProcessRecord r = null;
9162            if (caller != null) {
9163                r = getRecordForAppLocked(caller);
9164                if (r == null) {
9165                    throw new SecurityException(
9166                            "Unable to find app for caller " + caller
9167                          + " (pid=" + Binder.getCallingPid()
9168                          + ") when getting content provider " + name);
9169                }
9170            }
9171
9172            boolean checkCrossUser = true;
9173
9174            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9175
9176            // First check if this content provider has been published...
9177            cpr = mProviderMap.getProviderByName(name, userId);
9178            // If that didn't work, check if it exists for user 0 and then
9179            // verify that it's a singleton provider before using it.
9180            if (cpr == null && userId != UserHandle.USER_OWNER) {
9181                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9182                if (cpr != null) {
9183                    cpi = cpr.info;
9184                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9185                            cpi.name, cpi.flags)
9186                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9187                        userId = UserHandle.USER_OWNER;
9188                        checkCrossUser = false;
9189                    } else {
9190                        cpr = null;
9191                        cpi = null;
9192                    }
9193                }
9194            }
9195
9196            boolean providerRunning = cpr != null;
9197            if (providerRunning) {
9198                cpi = cpr.info;
9199                String msg;
9200                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9201                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9202                        != null) {
9203                    throw new SecurityException(msg);
9204                }
9205                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9206
9207                if (r != null && cpr.canRunHere(r)) {
9208                    // This provider has been published or is in the process
9209                    // of being published...  but it is also allowed to run
9210                    // in the caller's process, so don't make a connection
9211                    // and just let the caller instantiate its own instance.
9212                    ContentProviderHolder holder = cpr.newHolder(null);
9213                    // don't give caller the provider object, it needs
9214                    // to make its own.
9215                    holder.provider = null;
9216                    return holder;
9217                }
9218
9219                final long origId = Binder.clearCallingIdentity();
9220
9221                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9222
9223                // In this case the provider instance already exists, so we can
9224                // return it right away.
9225                conn = incProviderCountLocked(r, cpr, token, stable);
9226                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9227                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9228                        // If this is a perceptible app accessing the provider,
9229                        // make sure to count it as being accessed and thus
9230                        // back up on the LRU list.  This is good because
9231                        // content providers are often expensive to start.
9232                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9233                        updateLruProcessLocked(cpr.proc, false, null);
9234                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9235                    }
9236                }
9237
9238                if (cpr.proc != null) {
9239                    if (false) {
9240                        if (cpr.name.flattenToShortString().equals(
9241                                "com.android.providers.calendar/.CalendarProvider2")) {
9242                            Slog.v(TAG, "****************** KILLING "
9243                                + cpr.name.flattenToShortString());
9244                            Process.killProcess(cpr.proc.pid);
9245                        }
9246                    }
9247                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9248                    boolean success = updateOomAdjLocked(cpr.proc);
9249                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9250                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9251                    // NOTE: there is still a race here where a signal could be
9252                    // pending on the process even though we managed to update its
9253                    // adj level.  Not sure what to do about this, but at least
9254                    // the race is now smaller.
9255                    if (!success) {
9256                        // Uh oh...  it looks like the provider's process
9257                        // has been killed on us.  We need to wait for a new
9258                        // process to be started, and make sure its death
9259                        // doesn't kill our process.
9260                        Slog.i(TAG,
9261                                "Existing provider " + cpr.name.flattenToShortString()
9262                                + " is crashing; detaching " + r);
9263                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9264                        checkTime(startTime, "getContentProviderImpl: before appDied");
9265                        appDiedLocked(cpr.proc);
9266                        checkTime(startTime, "getContentProviderImpl: after appDied");
9267                        if (!lastRef) {
9268                            // This wasn't the last ref our process had on
9269                            // the provider...  we have now been killed, bail.
9270                            return null;
9271                        }
9272                        providerRunning = false;
9273                        conn = null;
9274                    }
9275                }
9276
9277                Binder.restoreCallingIdentity(origId);
9278            }
9279
9280            boolean singleton;
9281            if (!providerRunning) {
9282                try {
9283                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9284                    cpi = AppGlobals.getPackageManager().
9285                        resolveContentProvider(name,
9286                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9287                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9288                } catch (RemoteException ex) {
9289                }
9290                if (cpi == null) {
9291                    return null;
9292                }
9293                // If the provider is a singleton AND
9294                // (it's a call within the same user || the provider is a
9295                // privileged app)
9296                // Then allow connecting to the singleton provider
9297                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9298                        cpi.name, cpi.flags)
9299                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9300                if (singleton) {
9301                    userId = UserHandle.USER_OWNER;
9302                }
9303                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9304                checkTime(startTime, "getContentProviderImpl: got app info for user");
9305
9306                String msg;
9307                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9308                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9309                        != null) {
9310                    throw new SecurityException(msg);
9311                }
9312                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9313
9314                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9315                        && !cpi.processName.equals("system")) {
9316                    // If this content provider does not run in the system
9317                    // process, and the system is not yet ready to run other
9318                    // processes, then fail fast instead of hanging.
9319                    throw new IllegalArgumentException(
9320                            "Attempt to launch content provider before system ready");
9321                }
9322
9323                // Make sure that the user who owns this provider is running.  If not,
9324                // we don't want to allow it to run.
9325                if (!isUserRunningLocked(userId, false)) {
9326                    Slog.w(TAG, "Unable to launch app "
9327                            + cpi.applicationInfo.packageName + "/"
9328                            + cpi.applicationInfo.uid + " for provider "
9329                            + name + ": user " + userId + " is stopped");
9330                    return null;
9331                }
9332
9333                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9334                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9335                cpr = mProviderMap.getProviderByClass(comp, userId);
9336                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9337                final boolean firstClass = cpr == null;
9338                if (firstClass) {
9339                    final long ident = Binder.clearCallingIdentity();
9340                    try {
9341                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9342                        ApplicationInfo ai =
9343                            AppGlobals.getPackageManager().
9344                                getApplicationInfo(
9345                                        cpi.applicationInfo.packageName,
9346                                        STOCK_PM_FLAGS, userId);
9347                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9348                        if (ai == null) {
9349                            Slog.w(TAG, "No package info for content provider "
9350                                    + cpi.name);
9351                            return null;
9352                        }
9353                        ai = getAppInfoForUser(ai, userId);
9354                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9355                    } catch (RemoteException ex) {
9356                        // pm is in same process, this will never happen.
9357                    } finally {
9358                        Binder.restoreCallingIdentity(ident);
9359                    }
9360                }
9361
9362                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9363
9364                if (r != null && cpr.canRunHere(r)) {
9365                    // If this is a multiprocess provider, then just return its
9366                    // info and allow the caller to instantiate it.  Only do
9367                    // this if the provider is the same user as the caller's
9368                    // process, or can run as root (so can be in any process).
9369                    return cpr.newHolder(null);
9370                }
9371
9372                if (DEBUG_PROVIDER) {
9373                    RuntimeException e = new RuntimeException("here");
9374                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9375                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9376                }
9377
9378                // This is single process, and our app is now connecting to it.
9379                // See if we are already in the process of launching this
9380                // provider.
9381                final int N = mLaunchingProviders.size();
9382                int i;
9383                for (i=0; i<N; i++) {
9384                    if (mLaunchingProviders.get(i) == cpr) {
9385                        break;
9386                    }
9387                }
9388
9389                // If the provider is not already being launched, then get it
9390                // started.
9391                if (i >= N) {
9392                    final long origId = Binder.clearCallingIdentity();
9393
9394                    try {
9395                        // Content provider is now in use, its package can't be stopped.
9396                        try {
9397                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9398                            AppGlobals.getPackageManager().setPackageStoppedState(
9399                                    cpr.appInfo.packageName, false, userId);
9400                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9401                        } catch (RemoteException e) {
9402                        } catch (IllegalArgumentException e) {
9403                            Slog.w(TAG, "Failed trying to unstop package "
9404                                    + cpr.appInfo.packageName + ": " + e);
9405                        }
9406
9407                        // Use existing process if already started
9408                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9409                        ProcessRecord proc = getProcessRecordLocked(
9410                                cpi.processName, cpr.appInfo.uid, false);
9411                        if (proc != null && proc.thread != null) {
9412                            if (DEBUG_PROVIDER) {
9413                                Slog.d(TAG, "Installing in existing process " + proc);
9414                            }
9415                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9416                            proc.pubProviders.put(cpi.name, cpr);
9417                            try {
9418                                proc.thread.scheduleInstallProvider(cpi);
9419                            } catch (RemoteException e) {
9420                            }
9421                        } else {
9422                            checkTime(startTime, "getContentProviderImpl: before start process");
9423                            proc = startProcessLocked(cpi.processName,
9424                                    cpr.appInfo, false, 0, "content provider",
9425                                    new ComponentName(cpi.applicationInfo.packageName,
9426                                            cpi.name), false, false, false);
9427                            checkTime(startTime, "getContentProviderImpl: after start process");
9428                            if (proc == null) {
9429                                Slog.w(TAG, "Unable to launch app "
9430                                        + cpi.applicationInfo.packageName + "/"
9431                                        + cpi.applicationInfo.uid + " for provider "
9432                                        + name + ": process is bad");
9433                                return null;
9434                            }
9435                        }
9436                        cpr.launchingApp = proc;
9437                        mLaunchingProviders.add(cpr);
9438                    } finally {
9439                        Binder.restoreCallingIdentity(origId);
9440                    }
9441                }
9442
9443                checkTime(startTime, "getContentProviderImpl: updating data structures");
9444
9445                // Make sure the provider is published (the same provider class
9446                // may be published under multiple names).
9447                if (firstClass) {
9448                    mProviderMap.putProviderByClass(comp, cpr);
9449                }
9450
9451                mProviderMap.putProviderByName(name, cpr);
9452                conn = incProviderCountLocked(r, cpr, token, stable);
9453                if (conn != null) {
9454                    conn.waiting = true;
9455                }
9456            }
9457            checkTime(startTime, "getContentProviderImpl: done!");
9458        }
9459
9460        // Wait for the provider to be published...
9461        synchronized (cpr) {
9462            while (cpr.provider == null) {
9463                if (cpr.launchingApp == null) {
9464                    Slog.w(TAG, "Unable to launch app "
9465                            + cpi.applicationInfo.packageName + "/"
9466                            + cpi.applicationInfo.uid + " for provider "
9467                            + name + ": launching app became null");
9468                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9469                            UserHandle.getUserId(cpi.applicationInfo.uid),
9470                            cpi.applicationInfo.packageName,
9471                            cpi.applicationInfo.uid, name);
9472                    return null;
9473                }
9474                try {
9475                    if (DEBUG_MU) {
9476                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9477                                + cpr.launchingApp);
9478                    }
9479                    if (conn != null) {
9480                        conn.waiting = true;
9481                    }
9482                    cpr.wait();
9483                } catch (InterruptedException ex) {
9484                } finally {
9485                    if (conn != null) {
9486                        conn.waiting = false;
9487                    }
9488                }
9489            }
9490        }
9491        return cpr != null ? cpr.newHolder(conn) : null;
9492    }
9493
9494    @Override
9495    public final ContentProviderHolder getContentProvider(
9496            IApplicationThread caller, String name, int userId, boolean stable) {
9497        enforceNotIsolatedCaller("getContentProvider");
9498        if (caller == null) {
9499            String msg = "null IApplicationThread when getting content provider "
9500                    + name;
9501            Slog.w(TAG, msg);
9502            throw new SecurityException(msg);
9503        }
9504        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9505        // with cross-user grant.
9506        return getContentProviderImpl(caller, name, null, stable, userId);
9507    }
9508
9509    public ContentProviderHolder getContentProviderExternal(
9510            String name, int userId, IBinder token) {
9511        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9512            "Do not have permission in call getContentProviderExternal()");
9513        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9514                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9515        return getContentProviderExternalUnchecked(name, token, userId);
9516    }
9517
9518    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9519            IBinder token, int userId) {
9520        return getContentProviderImpl(null, name, token, true, userId);
9521    }
9522
9523    /**
9524     * Drop a content provider from a ProcessRecord's bookkeeping
9525     */
9526    public void removeContentProvider(IBinder connection, boolean stable) {
9527        enforceNotIsolatedCaller("removeContentProvider");
9528        long ident = Binder.clearCallingIdentity();
9529        try {
9530            synchronized (this) {
9531                ContentProviderConnection conn;
9532                try {
9533                    conn = (ContentProviderConnection)connection;
9534                } catch (ClassCastException e) {
9535                    String msg ="removeContentProvider: " + connection
9536                            + " not a ContentProviderConnection";
9537                    Slog.w(TAG, msg);
9538                    throw new IllegalArgumentException(msg);
9539                }
9540                if (conn == null) {
9541                    throw new NullPointerException("connection is null");
9542                }
9543                if (decProviderCountLocked(conn, null, null, stable)) {
9544                    updateOomAdjLocked();
9545                }
9546            }
9547        } finally {
9548            Binder.restoreCallingIdentity(ident);
9549        }
9550    }
9551
9552    public void removeContentProviderExternal(String name, IBinder token) {
9553        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9554            "Do not have permission in call removeContentProviderExternal()");
9555        int userId = UserHandle.getCallingUserId();
9556        long ident = Binder.clearCallingIdentity();
9557        try {
9558            removeContentProviderExternalUnchecked(name, token, userId);
9559        } finally {
9560            Binder.restoreCallingIdentity(ident);
9561        }
9562    }
9563
9564    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9565        synchronized (this) {
9566            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9567            if(cpr == null) {
9568                //remove from mProvidersByClass
9569                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9570                return;
9571            }
9572
9573            //update content provider record entry info
9574            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9575            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9576            if (localCpr.hasExternalProcessHandles()) {
9577                if (localCpr.removeExternalProcessHandleLocked(token)) {
9578                    updateOomAdjLocked();
9579                } else {
9580                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9581                            + " with no external reference for token: "
9582                            + token + ".");
9583                }
9584            } else {
9585                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9586                        + " with no external references.");
9587            }
9588        }
9589    }
9590
9591    public final void publishContentProviders(IApplicationThread caller,
9592            List<ContentProviderHolder> providers) {
9593        if (providers == null) {
9594            return;
9595        }
9596
9597        enforceNotIsolatedCaller("publishContentProviders");
9598        synchronized (this) {
9599            final ProcessRecord r = getRecordForAppLocked(caller);
9600            if (DEBUG_MU)
9601                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9602            if (r == null) {
9603                throw new SecurityException(
9604                        "Unable to find app for caller " + caller
9605                      + " (pid=" + Binder.getCallingPid()
9606                      + ") when publishing content providers");
9607            }
9608
9609            final long origId = Binder.clearCallingIdentity();
9610
9611            final int N = providers.size();
9612            for (int i=0; i<N; i++) {
9613                ContentProviderHolder src = providers.get(i);
9614                if (src == null || src.info == null || src.provider == null) {
9615                    continue;
9616                }
9617                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9618                if (DEBUG_MU)
9619                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9620                if (dst != null) {
9621                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9622                    mProviderMap.putProviderByClass(comp, dst);
9623                    String names[] = dst.info.authority.split(";");
9624                    for (int j = 0; j < names.length; j++) {
9625                        mProviderMap.putProviderByName(names[j], dst);
9626                    }
9627
9628                    int NL = mLaunchingProviders.size();
9629                    int j;
9630                    for (j=0; j<NL; j++) {
9631                        if (mLaunchingProviders.get(j) == dst) {
9632                            mLaunchingProviders.remove(j);
9633                            j--;
9634                            NL--;
9635                        }
9636                    }
9637                    synchronized (dst) {
9638                        dst.provider = src.provider;
9639                        dst.proc = r;
9640                        dst.notifyAll();
9641                    }
9642                    updateOomAdjLocked(r);
9643                }
9644            }
9645
9646            Binder.restoreCallingIdentity(origId);
9647        }
9648    }
9649
9650    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9651        ContentProviderConnection conn;
9652        try {
9653            conn = (ContentProviderConnection)connection;
9654        } catch (ClassCastException e) {
9655            String msg ="refContentProvider: " + connection
9656                    + " not a ContentProviderConnection";
9657            Slog.w(TAG, msg);
9658            throw new IllegalArgumentException(msg);
9659        }
9660        if (conn == null) {
9661            throw new NullPointerException("connection is null");
9662        }
9663
9664        synchronized (this) {
9665            if (stable > 0) {
9666                conn.numStableIncs += stable;
9667            }
9668            stable = conn.stableCount + stable;
9669            if (stable < 0) {
9670                throw new IllegalStateException("stableCount < 0: " + stable);
9671            }
9672
9673            if (unstable > 0) {
9674                conn.numUnstableIncs += unstable;
9675            }
9676            unstable = conn.unstableCount + unstable;
9677            if (unstable < 0) {
9678                throw new IllegalStateException("unstableCount < 0: " + unstable);
9679            }
9680
9681            if ((stable+unstable) <= 0) {
9682                throw new IllegalStateException("ref counts can't go to zero here: stable="
9683                        + stable + " unstable=" + unstable);
9684            }
9685            conn.stableCount = stable;
9686            conn.unstableCount = unstable;
9687            return !conn.dead;
9688        }
9689    }
9690
9691    public void unstableProviderDied(IBinder connection) {
9692        ContentProviderConnection conn;
9693        try {
9694            conn = (ContentProviderConnection)connection;
9695        } catch (ClassCastException e) {
9696            String msg ="refContentProvider: " + connection
9697                    + " not a ContentProviderConnection";
9698            Slog.w(TAG, msg);
9699            throw new IllegalArgumentException(msg);
9700        }
9701        if (conn == null) {
9702            throw new NullPointerException("connection is null");
9703        }
9704
9705        // Safely retrieve the content provider associated with the connection.
9706        IContentProvider provider;
9707        synchronized (this) {
9708            provider = conn.provider.provider;
9709        }
9710
9711        if (provider == null) {
9712            // Um, yeah, we're way ahead of you.
9713            return;
9714        }
9715
9716        // Make sure the caller is being honest with us.
9717        if (provider.asBinder().pingBinder()) {
9718            // Er, no, still looks good to us.
9719            synchronized (this) {
9720                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9721                        + " says " + conn + " died, but we don't agree");
9722                return;
9723            }
9724        }
9725
9726        // Well look at that!  It's dead!
9727        synchronized (this) {
9728            if (conn.provider.provider != provider) {
9729                // But something changed...  good enough.
9730                return;
9731            }
9732
9733            ProcessRecord proc = conn.provider.proc;
9734            if (proc == null || proc.thread == null) {
9735                // Seems like the process is already cleaned up.
9736                return;
9737            }
9738
9739            // As far as we're concerned, this is just like receiving a
9740            // death notification...  just a bit prematurely.
9741            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9742                    + ") early provider death");
9743            final long ident = Binder.clearCallingIdentity();
9744            try {
9745                appDiedLocked(proc);
9746            } finally {
9747                Binder.restoreCallingIdentity(ident);
9748            }
9749        }
9750    }
9751
9752    @Override
9753    public void appNotRespondingViaProvider(IBinder connection) {
9754        enforceCallingPermission(
9755                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9756
9757        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9758        if (conn == null) {
9759            Slog.w(TAG, "ContentProviderConnection is null");
9760            return;
9761        }
9762
9763        final ProcessRecord host = conn.provider.proc;
9764        if (host == null) {
9765            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9766            return;
9767        }
9768
9769        final long token = Binder.clearCallingIdentity();
9770        try {
9771            appNotResponding(host, null, null, false, "ContentProvider not responding");
9772        } finally {
9773            Binder.restoreCallingIdentity(token);
9774        }
9775    }
9776
9777    public final void installSystemProviders() {
9778        List<ProviderInfo> providers;
9779        synchronized (this) {
9780            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9781            providers = generateApplicationProvidersLocked(app);
9782            if (providers != null) {
9783                for (int i=providers.size()-1; i>=0; i--) {
9784                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9785                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9786                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9787                                + ": not system .apk");
9788                        providers.remove(i);
9789                    }
9790                }
9791            }
9792        }
9793        if (providers != null) {
9794            mSystemThread.installSystemProviders(providers);
9795        }
9796
9797        mCoreSettingsObserver = new CoreSettingsObserver(this);
9798
9799        //mUsageStatsService.monitorPackages();
9800    }
9801
9802    /**
9803     * Allows apps to retrieve the MIME type of a URI.
9804     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9805     * users, then it does not need permission to access the ContentProvider.
9806     * Either, it needs cross-user uri grants.
9807     *
9808     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9809     *
9810     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9811     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9812     */
9813    public String getProviderMimeType(Uri uri, int userId) {
9814        enforceNotIsolatedCaller("getProviderMimeType");
9815        final String name = uri.getAuthority();
9816        int callingUid = Binder.getCallingUid();
9817        int callingPid = Binder.getCallingPid();
9818        long ident = 0;
9819        boolean clearedIdentity = false;
9820        userId = unsafeConvertIncomingUser(userId);
9821        if (canClearIdentity(callingPid, callingUid, userId)) {
9822            clearedIdentity = true;
9823            ident = Binder.clearCallingIdentity();
9824        }
9825        ContentProviderHolder holder = null;
9826        try {
9827            holder = getContentProviderExternalUnchecked(name, null, userId);
9828            if (holder != null) {
9829                return holder.provider.getType(uri);
9830            }
9831        } catch (RemoteException e) {
9832            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9833            return null;
9834        } finally {
9835            // We need to clear the identity to call removeContentProviderExternalUnchecked
9836            if (!clearedIdentity) {
9837                ident = Binder.clearCallingIdentity();
9838            }
9839            try {
9840                if (holder != null) {
9841                    removeContentProviderExternalUnchecked(name, null, userId);
9842                }
9843            } finally {
9844                Binder.restoreCallingIdentity(ident);
9845            }
9846        }
9847
9848        return null;
9849    }
9850
9851    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9852        if (UserHandle.getUserId(callingUid) == userId) {
9853            return true;
9854        }
9855        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9856                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9857                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9858                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9859                return true;
9860        }
9861        return false;
9862    }
9863
9864    // =========================================================
9865    // GLOBAL MANAGEMENT
9866    // =========================================================
9867
9868    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9869            boolean isolated, int isolatedUid) {
9870        String proc = customProcess != null ? customProcess : info.processName;
9871        BatteryStatsImpl.Uid.Proc ps = null;
9872        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9873        int uid = info.uid;
9874        if (isolated) {
9875            if (isolatedUid == 0) {
9876                int userId = UserHandle.getUserId(uid);
9877                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9878                while (true) {
9879                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9880                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9881                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9882                    }
9883                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9884                    mNextIsolatedProcessUid++;
9885                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9886                        // No process for this uid, use it.
9887                        break;
9888                    }
9889                    stepsLeft--;
9890                    if (stepsLeft <= 0) {
9891                        return null;
9892                    }
9893                }
9894            } else {
9895                // Special case for startIsolatedProcess (internal only), where
9896                // the uid of the isolated process is specified by the caller.
9897                uid = isolatedUid;
9898            }
9899        }
9900        return new ProcessRecord(stats, info, proc, uid);
9901    }
9902
9903    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9904            String abiOverride) {
9905        ProcessRecord app;
9906        if (!isolated) {
9907            app = getProcessRecordLocked(info.processName, info.uid, true);
9908        } else {
9909            app = null;
9910        }
9911
9912        if (app == null) {
9913            app = newProcessRecordLocked(info, null, isolated, 0);
9914            mProcessNames.put(info.processName, app.uid, app);
9915            if (isolated) {
9916                mIsolatedProcesses.put(app.uid, app);
9917            }
9918            updateLruProcessLocked(app, false, null);
9919            updateOomAdjLocked();
9920        }
9921
9922        // This package really, really can not be stopped.
9923        try {
9924            AppGlobals.getPackageManager().setPackageStoppedState(
9925                    info.packageName, false, UserHandle.getUserId(app.uid));
9926        } catch (RemoteException e) {
9927        } catch (IllegalArgumentException e) {
9928            Slog.w(TAG, "Failed trying to unstop package "
9929                    + info.packageName + ": " + e);
9930        }
9931
9932        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9933                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9934            app.persistent = true;
9935            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9936        }
9937        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9938            mPersistentStartingProcesses.add(app);
9939            startProcessLocked(app, "added application", app.processName, abiOverride,
9940                    null /* entryPoint */, null /* entryPointArgs */);
9941        }
9942
9943        return app;
9944    }
9945
9946    public void unhandledBack() {
9947        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9948                "unhandledBack()");
9949
9950        synchronized(this) {
9951            final long origId = Binder.clearCallingIdentity();
9952            try {
9953                getFocusedStack().unhandledBackLocked();
9954            } finally {
9955                Binder.restoreCallingIdentity(origId);
9956            }
9957        }
9958    }
9959
9960    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9961        enforceNotIsolatedCaller("openContentUri");
9962        final int userId = UserHandle.getCallingUserId();
9963        String name = uri.getAuthority();
9964        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9965        ParcelFileDescriptor pfd = null;
9966        if (cph != null) {
9967            // We record the binder invoker's uid in thread-local storage before
9968            // going to the content provider to open the file.  Later, in the code
9969            // that handles all permissions checks, we look for this uid and use
9970            // that rather than the Activity Manager's own uid.  The effect is that
9971            // we do the check against the caller's permissions even though it looks
9972            // to the content provider like the Activity Manager itself is making
9973            // the request.
9974            Binder token = new Binder();
9975            sCallerIdentity.set(new Identity(
9976                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9977            try {
9978                pfd = cph.provider.openFile(null, uri, "r", null, token);
9979            } catch (FileNotFoundException e) {
9980                // do nothing; pfd will be returned null
9981            } finally {
9982                // Ensure that whatever happens, we clean up the identity state
9983                sCallerIdentity.remove();
9984            }
9985
9986            // We've got the fd now, so we're done with the provider.
9987            removeContentProviderExternalUnchecked(name, null, userId);
9988        } else {
9989            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9990        }
9991        return pfd;
9992    }
9993
9994    // Actually is sleeping or shutting down or whatever else in the future
9995    // is an inactive state.
9996    public boolean isSleepingOrShuttingDown() {
9997        return isSleeping() || mShuttingDown;
9998    }
9999
10000    public boolean isSleeping() {
10001        return mSleeping;
10002    }
10003
10004    void onWakefulnessChanged(int wakefulness) {
10005        synchronized(this) {
10006            mWakefulness = wakefulness;
10007            updateSleepIfNeededLocked();
10008        }
10009    }
10010
10011    void finishRunningVoiceLocked() {
10012        if (mRunningVoice) {
10013            mRunningVoice = false;
10014            updateSleepIfNeededLocked();
10015        }
10016    }
10017
10018    void updateSleepIfNeededLocked() {
10019        if (mSleeping && !shouldSleepLocked()) {
10020            mSleeping = false;
10021            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10022        } else if (!mSleeping && shouldSleepLocked()) {
10023            mSleeping = true;
10024            mStackSupervisor.goingToSleepLocked();
10025
10026            // Initialize the wake times of all processes.
10027            checkExcessivePowerUsageLocked(false);
10028            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10029            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10030            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10031        }
10032    }
10033
10034    private boolean shouldSleepLocked() {
10035        // Resume applications while running a voice interactor.
10036        if (mRunningVoice) {
10037            return false;
10038        }
10039
10040        switch (mWakefulness) {
10041            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10042            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10043                // If we're interactive but applications are already paused then defer
10044                // resuming them until the lock screen is hidden.
10045                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10046            case PowerManagerInternal.WAKEFULNESS_DOZING:
10047                // If we're dozing then pause applications whenever the lock screen is shown.
10048                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10049            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10050            default:
10051                // If we're asleep then pause applications unconditionally.
10052                return true;
10053        }
10054    }
10055
10056    /** Pokes the task persister. */
10057    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10058        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10059            // Never persist the home stack.
10060            return;
10061        }
10062        mTaskPersister.wakeup(task, flush);
10063    }
10064
10065    /** Notifies all listeners when the task stack has changed. */
10066    void notifyTaskStackChangedLocked() {
10067        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10068        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10069        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10070    }
10071
10072    @Override
10073    public boolean shutdown(int timeout) {
10074        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10075                != PackageManager.PERMISSION_GRANTED) {
10076            throw new SecurityException("Requires permission "
10077                    + android.Manifest.permission.SHUTDOWN);
10078        }
10079
10080        boolean timedout = false;
10081
10082        synchronized(this) {
10083            mShuttingDown = true;
10084            updateEventDispatchingLocked();
10085            timedout = mStackSupervisor.shutdownLocked(timeout);
10086        }
10087
10088        mAppOpsService.shutdown();
10089        if (mUsageStatsService != null) {
10090            mUsageStatsService.prepareShutdown();
10091        }
10092        mBatteryStatsService.shutdown();
10093        synchronized (this) {
10094            mProcessStats.shutdownLocked();
10095            notifyTaskPersisterLocked(null, true);
10096        }
10097
10098        return timedout;
10099    }
10100
10101    public final void activitySlept(IBinder token) {
10102        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10103
10104        final long origId = Binder.clearCallingIdentity();
10105
10106        synchronized (this) {
10107            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10108            if (r != null) {
10109                mStackSupervisor.activitySleptLocked(r);
10110            }
10111        }
10112
10113        Binder.restoreCallingIdentity(origId);
10114    }
10115
10116    private String lockScreenShownToString() {
10117        switch (mLockScreenShown) {
10118            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10119            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10120            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10121            default: return "Unknown=" + mLockScreenShown;
10122        }
10123    }
10124
10125    void logLockScreen(String msg) {
10126        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10127                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10128                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10129                + " mSleeping=" + mSleeping);
10130    }
10131
10132    void startRunningVoiceLocked() {
10133        if (!mRunningVoice) {
10134            mRunningVoice = true;
10135            updateSleepIfNeededLocked();
10136        }
10137    }
10138
10139    private void updateEventDispatchingLocked() {
10140        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10141    }
10142
10143    public void setLockScreenShown(boolean shown) {
10144        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10145                != PackageManager.PERMISSION_GRANTED) {
10146            throw new SecurityException("Requires permission "
10147                    + android.Manifest.permission.DEVICE_POWER);
10148        }
10149
10150        synchronized(this) {
10151            long ident = Binder.clearCallingIdentity();
10152            try {
10153                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10154                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10155                updateSleepIfNeededLocked();
10156            } finally {
10157                Binder.restoreCallingIdentity(ident);
10158            }
10159        }
10160    }
10161
10162    @Override
10163    public void stopAppSwitches() {
10164        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10165                != PackageManager.PERMISSION_GRANTED) {
10166            throw new SecurityException("Requires permission "
10167                    + android.Manifest.permission.STOP_APP_SWITCHES);
10168        }
10169
10170        synchronized(this) {
10171            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10172                    + APP_SWITCH_DELAY_TIME;
10173            mDidAppSwitch = false;
10174            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10175            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10176            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10177        }
10178    }
10179
10180    public void resumeAppSwitches() {
10181        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10182                != PackageManager.PERMISSION_GRANTED) {
10183            throw new SecurityException("Requires permission "
10184                    + android.Manifest.permission.STOP_APP_SWITCHES);
10185        }
10186
10187        synchronized(this) {
10188            // Note that we don't execute any pending app switches... we will
10189            // let those wait until either the timeout, or the next start
10190            // activity request.
10191            mAppSwitchesAllowedTime = 0;
10192        }
10193    }
10194
10195    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10196            int callingPid, int callingUid, String name) {
10197        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10198            return true;
10199        }
10200
10201        int perm = checkComponentPermission(
10202                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10203                sourceUid, -1, true);
10204        if (perm == PackageManager.PERMISSION_GRANTED) {
10205            return true;
10206        }
10207
10208        // If the actual IPC caller is different from the logical source, then
10209        // also see if they are allowed to control app switches.
10210        if (callingUid != -1 && callingUid != sourceUid) {
10211            perm = checkComponentPermission(
10212                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10213                    callingUid, -1, true);
10214            if (perm == PackageManager.PERMISSION_GRANTED) {
10215                return true;
10216            }
10217        }
10218
10219        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10220        return false;
10221    }
10222
10223    public void setDebugApp(String packageName, boolean waitForDebugger,
10224            boolean persistent) {
10225        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10226                "setDebugApp()");
10227
10228        long ident = Binder.clearCallingIdentity();
10229        try {
10230            // Note that this is not really thread safe if there are multiple
10231            // callers into it at the same time, but that's not a situation we
10232            // care about.
10233            if (persistent) {
10234                final ContentResolver resolver = mContext.getContentResolver();
10235                Settings.Global.putString(
10236                    resolver, Settings.Global.DEBUG_APP,
10237                    packageName);
10238                Settings.Global.putInt(
10239                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10240                    waitForDebugger ? 1 : 0);
10241            }
10242
10243            synchronized (this) {
10244                if (!persistent) {
10245                    mOrigDebugApp = mDebugApp;
10246                    mOrigWaitForDebugger = mWaitForDebugger;
10247                }
10248                mDebugApp = packageName;
10249                mWaitForDebugger = waitForDebugger;
10250                mDebugTransient = !persistent;
10251                if (packageName != null) {
10252                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10253                            false, UserHandle.USER_ALL, "set debug app");
10254                }
10255            }
10256        } finally {
10257            Binder.restoreCallingIdentity(ident);
10258        }
10259    }
10260
10261    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10262        synchronized (this) {
10263            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10264            if (!isDebuggable) {
10265                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10266                    throw new SecurityException("Process not debuggable: " + app.packageName);
10267                }
10268            }
10269
10270            mOpenGlTraceApp = processName;
10271        }
10272    }
10273
10274    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10275        synchronized (this) {
10276            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10277            if (!isDebuggable) {
10278                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10279                    throw new SecurityException("Process not debuggable: " + app.packageName);
10280                }
10281            }
10282            mProfileApp = processName;
10283            mProfileFile = profilerInfo.profileFile;
10284            if (mProfileFd != null) {
10285                try {
10286                    mProfileFd.close();
10287                } catch (IOException e) {
10288                }
10289                mProfileFd = null;
10290            }
10291            mProfileFd = profilerInfo.profileFd;
10292            mSamplingInterval = profilerInfo.samplingInterval;
10293            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10294            mProfileType = 0;
10295        }
10296    }
10297
10298    @Override
10299    public void setAlwaysFinish(boolean enabled) {
10300        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10301                "setAlwaysFinish()");
10302
10303        Settings.Global.putInt(
10304                mContext.getContentResolver(),
10305                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10306
10307        synchronized (this) {
10308            mAlwaysFinishActivities = enabled;
10309        }
10310    }
10311
10312    @Override
10313    public void setActivityController(IActivityController controller) {
10314        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10315                "setActivityController()");
10316        synchronized (this) {
10317            mController = controller;
10318            Watchdog.getInstance().setActivityController(controller);
10319        }
10320    }
10321
10322    @Override
10323    public void setUserIsMonkey(boolean userIsMonkey) {
10324        synchronized (this) {
10325            synchronized (mPidsSelfLocked) {
10326                final int callingPid = Binder.getCallingPid();
10327                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10328                if (precessRecord == null) {
10329                    throw new SecurityException("Unknown process: " + callingPid);
10330                }
10331                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10332                    throw new SecurityException("Only an instrumentation process "
10333                            + "with a UiAutomation can call setUserIsMonkey");
10334                }
10335            }
10336            mUserIsMonkey = userIsMonkey;
10337        }
10338    }
10339
10340    @Override
10341    public boolean isUserAMonkey() {
10342        synchronized (this) {
10343            // If there is a controller also implies the user is a monkey.
10344            return (mUserIsMonkey || mController != null);
10345        }
10346    }
10347
10348    public void requestBugReport() {
10349        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10350        SystemProperties.set("ctl.start", "bugreport");
10351    }
10352
10353    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10354        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10355    }
10356
10357    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10358        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10359            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10360        }
10361        return KEY_DISPATCHING_TIMEOUT;
10362    }
10363
10364    @Override
10365    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10366        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10367                != PackageManager.PERMISSION_GRANTED) {
10368            throw new SecurityException("Requires permission "
10369                    + android.Manifest.permission.FILTER_EVENTS);
10370        }
10371        ProcessRecord proc;
10372        long timeout;
10373        synchronized (this) {
10374            synchronized (mPidsSelfLocked) {
10375                proc = mPidsSelfLocked.get(pid);
10376            }
10377            timeout = getInputDispatchingTimeoutLocked(proc);
10378        }
10379
10380        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10381            return -1;
10382        }
10383
10384        return timeout;
10385    }
10386
10387    /**
10388     * Handle input dispatching timeouts.
10389     * Returns whether input dispatching should be aborted or not.
10390     */
10391    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10392            final ActivityRecord activity, final ActivityRecord parent,
10393            final boolean aboveSystem, String reason) {
10394        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10395                != PackageManager.PERMISSION_GRANTED) {
10396            throw new SecurityException("Requires permission "
10397                    + android.Manifest.permission.FILTER_EVENTS);
10398        }
10399
10400        final String annotation;
10401        if (reason == null) {
10402            annotation = "Input dispatching timed out";
10403        } else {
10404            annotation = "Input dispatching timed out (" + reason + ")";
10405        }
10406
10407        if (proc != null) {
10408            synchronized (this) {
10409                if (proc.debugging) {
10410                    return false;
10411                }
10412
10413                if (mDidDexOpt) {
10414                    // Give more time since we were dexopting.
10415                    mDidDexOpt = false;
10416                    return false;
10417                }
10418
10419                if (proc.instrumentationClass != null) {
10420                    Bundle info = new Bundle();
10421                    info.putString("shortMsg", "keyDispatchingTimedOut");
10422                    info.putString("longMsg", annotation);
10423                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10424                    return true;
10425                }
10426            }
10427            mHandler.post(new Runnable() {
10428                @Override
10429                public void run() {
10430                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10431                }
10432            });
10433        }
10434
10435        return true;
10436    }
10437
10438    public Bundle getAssistContextExtras(int requestType) {
10439        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10440                UserHandle.getCallingUserId());
10441        if (pae == null) {
10442            return null;
10443        }
10444        synchronized (pae) {
10445            while (!pae.haveResult) {
10446                try {
10447                    pae.wait();
10448                } catch (InterruptedException e) {
10449                }
10450            }
10451            if (pae.result != null) {
10452                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10453            }
10454        }
10455        synchronized (this) {
10456            mPendingAssistExtras.remove(pae);
10457            mHandler.removeCallbacks(pae);
10458        }
10459        return pae.extras;
10460    }
10461
10462    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10463            int userHandle) {
10464        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10465                "getAssistContextExtras()");
10466        PendingAssistExtras pae;
10467        Bundle extras = new Bundle();
10468        synchronized (this) {
10469            ActivityRecord activity = getFocusedStack().mResumedActivity;
10470            if (activity == null) {
10471                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10472                return null;
10473            }
10474            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10475            if (activity.app == null || activity.app.thread == null) {
10476                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10477                return null;
10478            }
10479            if (activity.app.pid == Binder.getCallingPid()) {
10480                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10481                return null;
10482            }
10483            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10484            try {
10485                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10486                        requestType);
10487                mPendingAssistExtras.add(pae);
10488                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10489            } catch (RemoteException e) {
10490                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10491                return null;
10492            }
10493            return pae;
10494        }
10495    }
10496
10497    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10498        PendingAssistExtras pae = (PendingAssistExtras)token;
10499        synchronized (pae) {
10500            pae.result = extras;
10501            pae.haveResult = true;
10502            pae.notifyAll();
10503            if (pae.intent == null) {
10504                // Caller is just waiting for the result.
10505                return;
10506            }
10507        }
10508
10509        // We are now ready to launch the assist activity.
10510        synchronized (this) {
10511            boolean exists = mPendingAssistExtras.remove(pae);
10512            mHandler.removeCallbacks(pae);
10513            if (!exists) {
10514                // Timed out.
10515                return;
10516            }
10517        }
10518        pae.intent.replaceExtras(extras);
10519        if (pae.hint != null) {
10520            pae.intent.putExtra(pae.hint, true);
10521        }
10522        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10523                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10524                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10525        closeSystemDialogs("assist");
10526        try {
10527            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10528        } catch (ActivityNotFoundException e) {
10529            Slog.w(TAG, "No activity to handle assist action.", e);
10530        }
10531    }
10532
10533    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10534        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10535    }
10536
10537    public void registerProcessObserver(IProcessObserver observer) {
10538        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10539                "registerProcessObserver()");
10540        synchronized (this) {
10541            mProcessObservers.register(observer);
10542        }
10543    }
10544
10545    @Override
10546    public void unregisterProcessObserver(IProcessObserver observer) {
10547        synchronized (this) {
10548            mProcessObservers.unregister(observer);
10549        }
10550    }
10551
10552    @Override
10553    public boolean convertFromTranslucent(IBinder token) {
10554        final long origId = Binder.clearCallingIdentity();
10555        try {
10556            synchronized (this) {
10557                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10558                if (r == null) {
10559                    return false;
10560                }
10561                final boolean translucentChanged = r.changeWindowTranslucency(true);
10562                if (translucentChanged) {
10563                    r.task.stack.releaseBackgroundResources();
10564                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10565                }
10566                mWindowManager.setAppFullscreen(token, true);
10567                return translucentChanged;
10568            }
10569        } finally {
10570            Binder.restoreCallingIdentity(origId);
10571        }
10572    }
10573
10574    @Override
10575    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10576        final long origId = Binder.clearCallingIdentity();
10577        try {
10578            synchronized (this) {
10579                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10580                if (r == null) {
10581                    return false;
10582                }
10583                int index = r.task.mActivities.lastIndexOf(r);
10584                if (index > 0) {
10585                    ActivityRecord under = r.task.mActivities.get(index - 1);
10586                    under.returningOptions = options;
10587                }
10588                final boolean translucentChanged = r.changeWindowTranslucency(false);
10589                if (translucentChanged) {
10590                    r.task.stack.convertToTranslucent(r);
10591                }
10592                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10593                mWindowManager.setAppFullscreen(token, false);
10594                return translucentChanged;
10595            }
10596        } finally {
10597            Binder.restoreCallingIdentity(origId);
10598        }
10599    }
10600
10601    @Override
10602    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10603        final long origId = Binder.clearCallingIdentity();
10604        try {
10605            synchronized (this) {
10606                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10607                if (r != null) {
10608                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10609                }
10610            }
10611            return false;
10612        } finally {
10613            Binder.restoreCallingIdentity(origId);
10614        }
10615    }
10616
10617    @Override
10618    public boolean isBackgroundVisibleBehind(IBinder token) {
10619        final long origId = Binder.clearCallingIdentity();
10620        try {
10621            synchronized (this) {
10622                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10623                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10624                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10625                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10626                return visible;
10627            }
10628        } finally {
10629            Binder.restoreCallingIdentity(origId);
10630        }
10631    }
10632
10633    @Override
10634    public ActivityOptions getActivityOptions(IBinder token) {
10635        final long origId = Binder.clearCallingIdentity();
10636        try {
10637            synchronized (this) {
10638                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10639                if (r != null) {
10640                    final ActivityOptions activityOptions = r.pendingOptions;
10641                    r.pendingOptions = null;
10642                    return activityOptions;
10643                }
10644                return null;
10645            }
10646        } finally {
10647            Binder.restoreCallingIdentity(origId);
10648        }
10649    }
10650
10651    @Override
10652    public void setImmersive(IBinder token, boolean immersive) {
10653        synchronized(this) {
10654            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10655            if (r == null) {
10656                throw new IllegalArgumentException();
10657            }
10658            r.immersive = immersive;
10659
10660            // update associated state if we're frontmost
10661            if (r == mFocusedActivity) {
10662                if (DEBUG_IMMERSIVE) {
10663                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10664                }
10665                applyUpdateLockStateLocked(r);
10666            }
10667        }
10668    }
10669
10670    @Override
10671    public boolean isImmersive(IBinder token) {
10672        synchronized (this) {
10673            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10674            if (r == null) {
10675                throw new IllegalArgumentException();
10676            }
10677            return r.immersive;
10678        }
10679    }
10680
10681    public boolean isTopActivityImmersive() {
10682        enforceNotIsolatedCaller("startActivity");
10683        synchronized (this) {
10684            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10685            return (r != null) ? r.immersive : false;
10686        }
10687    }
10688
10689    @Override
10690    public boolean isTopOfTask(IBinder token) {
10691        synchronized (this) {
10692            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10693            if (r == null) {
10694                throw new IllegalArgumentException();
10695            }
10696            return r.task.getTopActivity() == r;
10697        }
10698    }
10699
10700    public final void enterSafeMode() {
10701        synchronized(this) {
10702            // It only makes sense to do this before the system is ready
10703            // and started launching other packages.
10704            if (!mSystemReady) {
10705                try {
10706                    AppGlobals.getPackageManager().enterSafeMode();
10707                } catch (RemoteException e) {
10708                }
10709            }
10710
10711            mSafeMode = true;
10712        }
10713    }
10714
10715    public final void showSafeModeOverlay() {
10716        View v = LayoutInflater.from(mContext).inflate(
10717                com.android.internal.R.layout.safe_mode, null);
10718        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10719        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10720        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10721        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10722        lp.gravity = Gravity.BOTTOM | Gravity.START;
10723        lp.format = v.getBackground().getOpacity();
10724        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10725                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10726        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10727        ((WindowManager)mContext.getSystemService(
10728                Context.WINDOW_SERVICE)).addView(v, lp);
10729    }
10730
10731    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10732        if (!(sender instanceof PendingIntentRecord)) {
10733            return;
10734        }
10735        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10736        synchronized (stats) {
10737            if (mBatteryStatsService.isOnBattery()) {
10738                mBatteryStatsService.enforceCallingPermission();
10739                PendingIntentRecord rec = (PendingIntentRecord)sender;
10740                int MY_UID = Binder.getCallingUid();
10741                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10742                BatteryStatsImpl.Uid.Pkg pkg =
10743                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10744                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10745                pkg.incWakeupsLocked();
10746            }
10747        }
10748    }
10749
10750    public boolean killPids(int[] pids, String pReason, boolean secure) {
10751        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10752            throw new SecurityException("killPids only available to the system");
10753        }
10754        String reason = (pReason == null) ? "Unknown" : pReason;
10755        // XXX Note: don't acquire main activity lock here, because the window
10756        // manager calls in with its locks held.
10757
10758        boolean killed = false;
10759        synchronized (mPidsSelfLocked) {
10760            int[] types = new int[pids.length];
10761            int worstType = 0;
10762            for (int i=0; i<pids.length; i++) {
10763                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10764                if (proc != null) {
10765                    int type = proc.setAdj;
10766                    types[i] = type;
10767                    if (type > worstType) {
10768                        worstType = type;
10769                    }
10770                }
10771            }
10772
10773            // If the worst oom_adj is somewhere in the cached proc LRU range,
10774            // then constrain it so we will kill all cached procs.
10775            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10776                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10777                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10778            }
10779
10780            // If this is not a secure call, don't let it kill processes that
10781            // are important.
10782            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10783                worstType = ProcessList.SERVICE_ADJ;
10784            }
10785
10786            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10787            for (int i=0; i<pids.length; i++) {
10788                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10789                if (proc == null) {
10790                    continue;
10791                }
10792                int adj = proc.setAdj;
10793                if (adj >= worstType && !proc.killedByAm) {
10794                    proc.kill(reason, true);
10795                    killed = true;
10796                }
10797            }
10798        }
10799        return killed;
10800    }
10801
10802    @Override
10803    public void killUid(int uid, String reason) {
10804        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10805            throw new SecurityException("killUid only available to the system");
10806        }
10807        synchronized (this) {
10808            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10809                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10810                    reason != null ? reason : "kill uid");
10811        }
10812    }
10813
10814    @Override
10815    public boolean killProcessesBelowForeground(String reason) {
10816        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10817            throw new SecurityException("killProcessesBelowForeground() only available to system");
10818        }
10819
10820        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10821    }
10822
10823    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10824        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10825            throw new SecurityException("killProcessesBelowAdj() only available to system");
10826        }
10827
10828        boolean killed = false;
10829        synchronized (mPidsSelfLocked) {
10830            final int size = mPidsSelfLocked.size();
10831            for (int i = 0; i < size; i++) {
10832                final int pid = mPidsSelfLocked.keyAt(i);
10833                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10834                if (proc == null) continue;
10835
10836                final int adj = proc.setAdj;
10837                if (adj > belowAdj && !proc.killedByAm) {
10838                    proc.kill(reason, true);
10839                    killed = true;
10840                }
10841            }
10842        }
10843        return killed;
10844    }
10845
10846    @Override
10847    public void hang(final IBinder who, boolean allowRestart) {
10848        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10849                != PackageManager.PERMISSION_GRANTED) {
10850            throw new SecurityException("Requires permission "
10851                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10852        }
10853
10854        final IBinder.DeathRecipient death = new DeathRecipient() {
10855            @Override
10856            public void binderDied() {
10857                synchronized (this) {
10858                    notifyAll();
10859                }
10860            }
10861        };
10862
10863        try {
10864            who.linkToDeath(death, 0);
10865        } catch (RemoteException e) {
10866            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10867            return;
10868        }
10869
10870        synchronized (this) {
10871            Watchdog.getInstance().setAllowRestart(allowRestart);
10872            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10873            synchronized (death) {
10874                while (who.isBinderAlive()) {
10875                    try {
10876                        death.wait();
10877                    } catch (InterruptedException e) {
10878                    }
10879                }
10880            }
10881            Watchdog.getInstance().setAllowRestart(true);
10882        }
10883    }
10884
10885    @Override
10886    public void restart() {
10887        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10888                != PackageManager.PERMISSION_GRANTED) {
10889            throw new SecurityException("Requires permission "
10890                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10891        }
10892
10893        Log.i(TAG, "Sending shutdown broadcast...");
10894
10895        BroadcastReceiver br = new BroadcastReceiver() {
10896            @Override public void onReceive(Context context, Intent intent) {
10897                // Now the broadcast is done, finish up the low-level shutdown.
10898                Log.i(TAG, "Shutting down activity manager...");
10899                shutdown(10000);
10900                Log.i(TAG, "Shutdown complete, restarting!");
10901                Process.killProcess(Process.myPid());
10902                System.exit(10);
10903            }
10904        };
10905
10906        // First send the high-level shut down broadcast.
10907        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10908        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10909        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10910        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10911        mContext.sendOrderedBroadcastAsUser(intent,
10912                UserHandle.ALL, null, br, mHandler, 0, null, null);
10913        */
10914        br.onReceive(mContext, intent);
10915    }
10916
10917    private long getLowRamTimeSinceIdle(long now) {
10918        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10919    }
10920
10921    @Override
10922    public void performIdleMaintenance() {
10923        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10924                != PackageManager.PERMISSION_GRANTED) {
10925            throw new SecurityException("Requires permission "
10926                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10927        }
10928
10929        synchronized (this) {
10930            final long now = SystemClock.uptimeMillis();
10931            final long timeSinceLastIdle = now - mLastIdleTime;
10932            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10933            mLastIdleTime = now;
10934            mLowRamTimeSinceLastIdle = 0;
10935            if (mLowRamStartTime != 0) {
10936                mLowRamStartTime = now;
10937            }
10938
10939            StringBuilder sb = new StringBuilder(128);
10940            sb.append("Idle maintenance over ");
10941            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10942            sb.append(" low RAM for ");
10943            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10944            Slog.i(TAG, sb.toString());
10945
10946            // If at least 1/3 of our time since the last idle period has been spent
10947            // with RAM low, then we want to kill processes.
10948            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10949
10950            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10951                ProcessRecord proc = mLruProcesses.get(i);
10952                if (proc.notCachedSinceIdle) {
10953                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10954                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10955                        if (doKilling && proc.initialIdlePss != 0
10956                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10957                            sb = new StringBuilder(128);
10958                            sb.append("Kill");
10959                            sb.append(proc.processName);
10960                            sb.append(" in idle maint: pss=");
10961                            sb.append(proc.lastPss);
10962                            sb.append(", initialPss=");
10963                            sb.append(proc.initialIdlePss);
10964                            sb.append(", period=");
10965                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10966                            sb.append(", lowRamPeriod=");
10967                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10968                            Slog.wtfQuiet(TAG, sb.toString());
10969                            proc.kill("idle maint (pss " + proc.lastPss
10970                                    + " from " + proc.initialIdlePss + ")", true);
10971                        }
10972                    }
10973                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10974                    proc.notCachedSinceIdle = true;
10975                    proc.initialIdlePss = 0;
10976                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10977                            mTestPssMode, isSleeping(), now);
10978                }
10979            }
10980
10981            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10982            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10983        }
10984    }
10985
10986    private void retrieveSettings() {
10987        final ContentResolver resolver = mContext.getContentResolver();
10988        String debugApp = Settings.Global.getString(
10989            resolver, Settings.Global.DEBUG_APP);
10990        boolean waitForDebugger = Settings.Global.getInt(
10991            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10992        boolean alwaysFinishActivities = Settings.Global.getInt(
10993            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10994        boolean forceRtl = Settings.Global.getInt(
10995                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10996        // Transfer any global setting for forcing RTL layout, into a System Property
10997        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10998
10999        Configuration configuration = new Configuration();
11000        Settings.System.getConfiguration(resolver, configuration);
11001        if (forceRtl) {
11002            // This will take care of setting the correct layout direction flags
11003            configuration.setLayoutDirection(configuration.locale);
11004        }
11005
11006        synchronized (this) {
11007            mDebugApp = mOrigDebugApp = debugApp;
11008            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11009            mAlwaysFinishActivities = alwaysFinishActivities;
11010            // This happens before any activities are started, so we can
11011            // change mConfiguration in-place.
11012            updateConfigurationLocked(configuration, null, false, true);
11013            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11014        }
11015    }
11016
11017    /** Loads resources after the current configuration has been set. */
11018    private void loadResourcesOnSystemReady() {
11019        final Resources res = mContext.getResources();
11020        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11021        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11022        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11023    }
11024
11025    public boolean testIsSystemReady() {
11026        // no need to synchronize(this) just to read & return the value
11027        return mSystemReady;
11028    }
11029
11030    private static File getCalledPreBootReceiversFile() {
11031        File dataDir = Environment.getDataDirectory();
11032        File systemDir = new File(dataDir, "system");
11033        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11034        return fname;
11035    }
11036
11037    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11038        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11039        File file = getCalledPreBootReceiversFile();
11040        FileInputStream fis = null;
11041        try {
11042            fis = new FileInputStream(file);
11043            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11044            int fvers = dis.readInt();
11045            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11046                String vers = dis.readUTF();
11047                String codename = dis.readUTF();
11048                String build = dis.readUTF();
11049                if (android.os.Build.VERSION.RELEASE.equals(vers)
11050                        && android.os.Build.VERSION.CODENAME.equals(codename)
11051                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11052                    int num = dis.readInt();
11053                    while (num > 0) {
11054                        num--;
11055                        String pkg = dis.readUTF();
11056                        String cls = dis.readUTF();
11057                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11058                    }
11059                }
11060            }
11061        } catch (FileNotFoundException e) {
11062        } catch (IOException e) {
11063            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11064        } finally {
11065            if (fis != null) {
11066                try {
11067                    fis.close();
11068                } catch (IOException e) {
11069                }
11070            }
11071        }
11072        return lastDoneReceivers;
11073    }
11074
11075    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11076        File file = getCalledPreBootReceiversFile();
11077        FileOutputStream fos = null;
11078        DataOutputStream dos = null;
11079        try {
11080            fos = new FileOutputStream(file);
11081            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11082            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11083            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11084            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11085            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11086            dos.writeInt(list.size());
11087            for (int i=0; i<list.size(); i++) {
11088                dos.writeUTF(list.get(i).getPackageName());
11089                dos.writeUTF(list.get(i).getClassName());
11090            }
11091        } catch (IOException e) {
11092            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11093            file.delete();
11094        } finally {
11095            FileUtils.sync(fos);
11096            if (dos != null) {
11097                try {
11098                    dos.close();
11099                } catch (IOException e) {
11100                    // TODO Auto-generated catch block
11101                    e.printStackTrace();
11102                }
11103            }
11104        }
11105    }
11106
11107    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11108            ArrayList<ComponentName> doneReceivers, int userId) {
11109        boolean waitingUpdate = false;
11110        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11111        List<ResolveInfo> ris = null;
11112        try {
11113            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11114                    intent, null, 0, userId);
11115        } catch (RemoteException e) {
11116        }
11117        if (ris != null) {
11118            for (int i=ris.size()-1; i>=0; i--) {
11119                if ((ris.get(i).activityInfo.applicationInfo.flags
11120                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11121                    ris.remove(i);
11122                }
11123            }
11124            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11125
11126            // For User 0, load the version number. When delivering to a new user, deliver
11127            // to all receivers.
11128            if (userId == UserHandle.USER_OWNER) {
11129                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11130                for (int i=0; i<ris.size(); i++) {
11131                    ActivityInfo ai = ris.get(i).activityInfo;
11132                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11133                    if (lastDoneReceivers.contains(comp)) {
11134                        // We already did the pre boot receiver for this app with the current
11135                        // platform version, so don't do it again...
11136                        ris.remove(i);
11137                        i--;
11138                        // ...however, do keep it as one that has been done, so we don't
11139                        // forget about it when rewriting the file of last done receivers.
11140                        doneReceivers.add(comp);
11141                    }
11142                }
11143            }
11144
11145            // If primary user, send broadcast to all available users, else just to userId
11146            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11147                    : new int[] { userId };
11148            for (int i = 0; i < ris.size(); i++) {
11149                ActivityInfo ai = ris.get(i).activityInfo;
11150                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11151                doneReceivers.add(comp);
11152                intent.setComponent(comp);
11153                for (int j=0; j<users.length; j++) {
11154                    IIntentReceiver finisher = null;
11155                    // On last receiver and user, set up a completion callback
11156                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11157                        finisher = new IIntentReceiver.Stub() {
11158                            public void performReceive(Intent intent, int resultCode,
11159                                    String data, Bundle extras, boolean ordered,
11160                                    boolean sticky, int sendingUser) {
11161                                // The raw IIntentReceiver interface is called
11162                                // with the AM lock held, so redispatch to
11163                                // execute our code without the lock.
11164                                mHandler.post(onFinishCallback);
11165                            }
11166                        };
11167                    }
11168                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11169                            + " for user " + users[j]);
11170                    broadcastIntentLocked(null, null, intent, null, finisher,
11171                            0, null, null, null, AppOpsManager.OP_NONE,
11172                            true, false, MY_PID, Process.SYSTEM_UID,
11173                            users[j]);
11174                    if (finisher != null) {
11175                        waitingUpdate = true;
11176                    }
11177                }
11178            }
11179        }
11180
11181        return waitingUpdate;
11182    }
11183
11184    public void systemReady(final Runnable goingCallback) {
11185        synchronized(this) {
11186            if (mSystemReady) {
11187                // If we're done calling all the receivers, run the next "boot phase" passed in
11188                // by the SystemServer
11189                if (goingCallback != null) {
11190                    goingCallback.run();
11191                }
11192                return;
11193            }
11194
11195            // Make sure we have the current profile info, since it is needed for
11196            // security checks.
11197            updateCurrentProfileIdsLocked();
11198
11199            if (mRecentTasks == null) {
11200                mRecentTasks = mTaskPersister.restoreTasksLocked();
11201                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11202                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11203                mTaskPersister.startPersisting();
11204            }
11205
11206            // Check to see if there are any update receivers to run.
11207            if (!mDidUpdate) {
11208                if (mWaitingUpdate) {
11209                    return;
11210                }
11211                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11212                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11213                    public void run() {
11214                        synchronized (ActivityManagerService.this) {
11215                            mDidUpdate = true;
11216                        }
11217                        writeLastDonePreBootReceivers(doneReceivers);
11218                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11219                                false);
11220                        systemReady(goingCallback);
11221                    }
11222                }, doneReceivers, UserHandle.USER_OWNER);
11223
11224                if (mWaitingUpdate) {
11225                    return;
11226                }
11227                mDidUpdate = true;
11228            }
11229
11230            mAppOpsService.systemReady();
11231            mSystemReady = true;
11232        }
11233
11234        ArrayList<ProcessRecord> procsToKill = null;
11235        synchronized(mPidsSelfLocked) {
11236            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11237                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11238                if (!isAllowedWhileBooting(proc.info)){
11239                    if (procsToKill == null) {
11240                        procsToKill = new ArrayList<ProcessRecord>();
11241                    }
11242                    procsToKill.add(proc);
11243                }
11244            }
11245        }
11246
11247        synchronized(this) {
11248            if (procsToKill != null) {
11249                for (int i=procsToKill.size()-1; i>=0; i--) {
11250                    ProcessRecord proc = procsToKill.get(i);
11251                    Slog.i(TAG, "Removing system update proc: " + proc);
11252                    removeProcessLocked(proc, true, false, "system update done");
11253                }
11254            }
11255
11256            // Now that we have cleaned up any update processes, we
11257            // are ready to start launching real processes and know that
11258            // we won't trample on them any more.
11259            mProcessesReady = true;
11260        }
11261
11262        Slog.i(TAG, "System now ready");
11263        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11264            SystemClock.uptimeMillis());
11265
11266        synchronized(this) {
11267            // Make sure we have no pre-ready processes sitting around.
11268
11269            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11270                ResolveInfo ri = mContext.getPackageManager()
11271                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11272                                STOCK_PM_FLAGS);
11273                CharSequence errorMsg = null;
11274                if (ri != null) {
11275                    ActivityInfo ai = ri.activityInfo;
11276                    ApplicationInfo app = ai.applicationInfo;
11277                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11278                        mTopAction = Intent.ACTION_FACTORY_TEST;
11279                        mTopData = null;
11280                        mTopComponent = new ComponentName(app.packageName,
11281                                ai.name);
11282                    } else {
11283                        errorMsg = mContext.getResources().getText(
11284                                com.android.internal.R.string.factorytest_not_system);
11285                    }
11286                } else {
11287                    errorMsg = mContext.getResources().getText(
11288                            com.android.internal.R.string.factorytest_no_action);
11289                }
11290                if (errorMsg != null) {
11291                    mTopAction = null;
11292                    mTopData = null;
11293                    mTopComponent = null;
11294                    Message msg = Message.obtain();
11295                    msg.what = SHOW_FACTORY_ERROR_MSG;
11296                    msg.getData().putCharSequence("msg", errorMsg);
11297                    mHandler.sendMessage(msg);
11298                }
11299            }
11300        }
11301
11302        retrieveSettings();
11303        loadResourcesOnSystemReady();
11304
11305        synchronized (this) {
11306            readGrantedUriPermissionsLocked();
11307        }
11308
11309        if (goingCallback != null) goingCallback.run();
11310
11311        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11312                Integer.toString(mCurrentUserId), mCurrentUserId);
11313        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11314                Integer.toString(mCurrentUserId), mCurrentUserId);
11315        mSystemServiceManager.startUser(mCurrentUserId);
11316
11317        synchronized (this) {
11318            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11319                try {
11320                    List apps = AppGlobals.getPackageManager().
11321                        getPersistentApplications(STOCK_PM_FLAGS);
11322                    if (apps != null) {
11323                        int N = apps.size();
11324                        int i;
11325                        for (i=0; i<N; i++) {
11326                            ApplicationInfo info
11327                                = (ApplicationInfo)apps.get(i);
11328                            if (info != null &&
11329                                    !info.packageName.equals("android")) {
11330                                addAppLocked(info, false, null /* ABI override */);
11331                            }
11332                        }
11333                    }
11334                } catch (RemoteException ex) {
11335                    // pm is in same process, this will never happen.
11336                }
11337            }
11338
11339            // Start up initial activity.
11340            mBooting = true;
11341            startHomeActivityLocked(mCurrentUserId);
11342
11343            try {
11344                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11345                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11346                            + " data partition or your device will be unstable.");
11347                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11348                }
11349            } catch (RemoteException e) {
11350            }
11351
11352            if (!Build.isFingerprintConsistent()) {
11353                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11354                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11355            }
11356
11357            long ident = Binder.clearCallingIdentity();
11358            try {
11359                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11360                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11361                        | Intent.FLAG_RECEIVER_FOREGROUND);
11362                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11363                broadcastIntentLocked(null, null, intent,
11364                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11365                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11366                intent = new Intent(Intent.ACTION_USER_STARTING);
11367                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11368                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11369                broadcastIntentLocked(null, null, intent,
11370                        null, new IIntentReceiver.Stub() {
11371                            @Override
11372                            public void performReceive(Intent intent, int resultCode, String data,
11373                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11374                                    throws RemoteException {
11375                            }
11376                        }, 0, null, null,
11377                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11378                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11379            } catch (Throwable t) {
11380                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11381            } finally {
11382                Binder.restoreCallingIdentity(ident);
11383            }
11384            mStackSupervisor.resumeTopActivitiesLocked();
11385            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11386        }
11387    }
11388
11389    private boolean makeAppCrashingLocked(ProcessRecord app,
11390            String shortMsg, String longMsg, String stackTrace) {
11391        app.crashing = true;
11392        app.crashingReport = generateProcessError(app,
11393                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11394        startAppProblemLocked(app);
11395        app.stopFreezingAllLocked();
11396        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11397    }
11398
11399    private void makeAppNotRespondingLocked(ProcessRecord app,
11400            String activity, String shortMsg, String longMsg) {
11401        app.notResponding = true;
11402        app.notRespondingReport = generateProcessError(app,
11403                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11404                activity, shortMsg, longMsg, null);
11405        startAppProblemLocked(app);
11406        app.stopFreezingAllLocked();
11407    }
11408
11409    /**
11410     * Generate a process error record, suitable for attachment to a ProcessRecord.
11411     *
11412     * @param app The ProcessRecord in which the error occurred.
11413     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11414     *                      ActivityManager.AppErrorStateInfo
11415     * @param activity The activity associated with the crash, if known.
11416     * @param shortMsg Short message describing the crash.
11417     * @param longMsg Long message describing the crash.
11418     * @param stackTrace Full crash stack trace, may be null.
11419     *
11420     * @return Returns a fully-formed AppErrorStateInfo record.
11421     */
11422    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11423            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11424        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11425
11426        report.condition = condition;
11427        report.processName = app.processName;
11428        report.pid = app.pid;
11429        report.uid = app.info.uid;
11430        report.tag = activity;
11431        report.shortMsg = shortMsg;
11432        report.longMsg = longMsg;
11433        report.stackTrace = stackTrace;
11434
11435        return report;
11436    }
11437
11438    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11439        synchronized (this) {
11440            app.crashing = false;
11441            app.crashingReport = null;
11442            app.notResponding = false;
11443            app.notRespondingReport = null;
11444            if (app.anrDialog == fromDialog) {
11445                app.anrDialog = null;
11446            }
11447            if (app.waitDialog == fromDialog) {
11448                app.waitDialog = null;
11449            }
11450            if (app.pid > 0 && app.pid != MY_PID) {
11451                handleAppCrashLocked(app, null, null, null);
11452                app.kill("user request after error", true);
11453            }
11454        }
11455    }
11456
11457    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11458            String stackTrace) {
11459        long now = SystemClock.uptimeMillis();
11460
11461        Long crashTime;
11462        if (!app.isolated) {
11463            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11464        } else {
11465            crashTime = null;
11466        }
11467        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11468            // This process loses!
11469            Slog.w(TAG, "Process " + app.info.processName
11470                    + " has crashed too many times: killing!");
11471            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11472                    app.userId, app.info.processName, app.uid);
11473            mStackSupervisor.handleAppCrashLocked(app);
11474            if (!app.persistent) {
11475                // We don't want to start this process again until the user
11476                // explicitly does so...  but for persistent process, we really
11477                // need to keep it running.  If a persistent process is actually
11478                // repeatedly crashing, then badness for everyone.
11479                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11480                        app.info.processName);
11481                if (!app.isolated) {
11482                    // XXX We don't have a way to mark isolated processes
11483                    // as bad, since they don't have a peristent identity.
11484                    mBadProcesses.put(app.info.processName, app.uid,
11485                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11486                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11487                }
11488                app.bad = true;
11489                app.removed = true;
11490                // Don't let services in this process be restarted and potentially
11491                // annoy the user repeatedly.  Unless it is persistent, since those
11492                // processes run critical code.
11493                removeProcessLocked(app, false, false, "crash");
11494                mStackSupervisor.resumeTopActivitiesLocked();
11495                return false;
11496            }
11497            mStackSupervisor.resumeTopActivitiesLocked();
11498        } else {
11499            mStackSupervisor.finishTopRunningActivityLocked(app);
11500        }
11501
11502        // Bump up the crash count of any services currently running in the proc.
11503        for (int i=app.services.size()-1; i>=0; i--) {
11504            // Any services running in the application need to be placed
11505            // back in the pending list.
11506            ServiceRecord sr = app.services.valueAt(i);
11507            sr.crashCount++;
11508        }
11509
11510        // If the crashing process is what we consider to be the "home process" and it has been
11511        // replaced by a third-party app, clear the package preferred activities from packages
11512        // with a home activity running in the process to prevent a repeatedly crashing app
11513        // from blocking the user to manually clear the list.
11514        final ArrayList<ActivityRecord> activities = app.activities;
11515        if (app == mHomeProcess && activities.size() > 0
11516                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11517            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11518                final ActivityRecord r = activities.get(activityNdx);
11519                if (r.isHomeActivity()) {
11520                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11521                    try {
11522                        ActivityThread.getPackageManager()
11523                                .clearPackagePreferredActivities(r.packageName);
11524                    } catch (RemoteException c) {
11525                        // pm is in same process, this will never happen.
11526                    }
11527                }
11528            }
11529        }
11530
11531        if (!app.isolated) {
11532            // XXX Can't keep track of crash times for isolated processes,
11533            // because they don't have a perisistent identity.
11534            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11535        }
11536
11537        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11538        return true;
11539    }
11540
11541    void startAppProblemLocked(ProcessRecord app) {
11542        // If this app is not running under the current user, then we
11543        // can't give it a report button because that would require
11544        // launching the report UI under a different user.
11545        app.errorReportReceiver = null;
11546
11547        for (int userId : mCurrentProfileIds) {
11548            if (app.userId == userId) {
11549                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11550                        mContext, app.info.packageName, app.info.flags);
11551            }
11552        }
11553        skipCurrentReceiverLocked(app);
11554    }
11555
11556    void skipCurrentReceiverLocked(ProcessRecord app) {
11557        for (BroadcastQueue queue : mBroadcastQueues) {
11558            queue.skipCurrentReceiverLocked(app);
11559        }
11560    }
11561
11562    /**
11563     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11564     * The application process will exit immediately after this call returns.
11565     * @param app object of the crashing app, null for the system server
11566     * @param crashInfo describing the exception
11567     */
11568    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11569        ProcessRecord r = findAppProcess(app, "Crash");
11570        final String processName = app == null ? "system_server"
11571                : (r == null ? "unknown" : r.processName);
11572
11573        handleApplicationCrashInner("crash", r, processName, crashInfo);
11574    }
11575
11576    /* Native crash reporting uses this inner version because it needs to be somewhat
11577     * decoupled from the AM-managed cleanup lifecycle
11578     */
11579    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11580            ApplicationErrorReport.CrashInfo crashInfo) {
11581        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11582                UserHandle.getUserId(Binder.getCallingUid()), processName,
11583                r == null ? -1 : r.info.flags,
11584                crashInfo.exceptionClassName,
11585                crashInfo.exceptionMessage,
11586                crashInfo.throwFileName,
11587                crashInfo.throwLineNumber);
11588
11589        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11590
11591        crashApplication(r, crashInfo);
11592    }
11593
11594    public void handleApplicationStrictModeViolation(
11595            IBinder app,
11596            int violationMask,
11597            StrictMode.ViolationInfo info) {
11598        ProcessRecord r = findAppProcess(app, "StrictMode");
11599        if (r == null) {
11600            return;
11601        }
11602
11603        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11604            Integer stackFingerprint = info.hashCode();
11605            boolean logIt = true;
11606            synchronized (mAlreadyLoggedViolatedStacks) {
11607                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11608                    logIt = false;
11609                    // TODO: sub-sample into EventLog for these, with
11610                    // the info.durationMillis?  Then we'd get
11611                    // the relative pain numbers, without logging all
11612                    // the stack traces repeatedly.  We'd want to do
11613                    // likewise in the client code, which also does
11614                    // dup suppression, before the Binder call.
11615                } else {
11616                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11617                        mAlreadyLoggedViolatedStacks.clear();
11618                    }
11619                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11620                }
11621            }
11622            if (logIt) {
11623                logStrictModeViolationToDropBox(r, info);
11624            }
11625        }
11626
11627        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11628            AppErrorResult result = new AppErrorResult();
11629            synchronized (this) {
11630                final long origId = Binder.clearCallingIdentity();
11631
11632                Message msg = Message.obtain();
11633                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11634                HashMap<String, Object> data = new HashMap<String, Object>();
11635                data.put("result", result);
11636                data.put("app", r);
11637                data.put("violationMask", violationMask);
11638                data.put("info", info);
11639                msg.obj = data;
11640                mHandler.sendMessage(msg);
11641
11642                Binder.restoreCallingIdentity(origId);
11643            }
11644            int res = result.get();
11645            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11646        }
11647    }
11648
11649    // Depending on the policy in effect, there could be a bunch of
11650    // these in quick succession so we try to batch these together to
11651    // minimize disk writes, number of dropbox entries, and maximize
11652    // compression, by having more fewer, larger records.
11653    private void logStrictModeViolationToDropBox(
11654            ProcessRecord process,
11655            StrictMode.ViolationInfo info) {
11656        if (info == null) {
11657            return;
11658        }
11659        final boolean isSystemApp = process == null ||
11660                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11661                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11662        final String processName = process == null ? "unknown" : process.processName;
11663        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11664        final DropBoxManager dbox = (DropBoxManager)
11665                mContext.getSystemService(Context.DROPBOX_SERVICE);
11666
11667        // Exit early if the dropbox isn't configured to accept this report type.
11668        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11669
11670        boolean bufferWasEmpty;
11671        boolean needsFlush;
11672        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11673        synchronized (sb) {
11674            bufferWasEmpty = sb.length() == 0;
11675            appendDropBoxProcessHeaders(process, processName, sb);
11676            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11677            sb.append("System-App: ").append(isSystemApp).append("\n");
11678            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11679            if (info.violationNumThisLoop != 0) {
11680                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11681            }
11682            if (info.numAnimationsRunning != 0) {
11683                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11684            }
11685            if (info.broadcastIntentAction != null) {
11686                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11687            }
11688            if (info.durationMillis != -1) {
11689                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11690            }
11691            if (info.numInstances != -1) {
11692                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11693            }
11694            if (info.tags != null) {
11695                for (String tag : info.tags) {
11696                    sb.append("Span-Tag: ").append(tag).append("\n");
11697                }
11698            }
11699            sb.append("\n");
11700            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11701                sb.append(info.crashInfo.stackTrace);
11702            }
11703            sb.append("\n");
11704
11705            // Only buffer up to ~64k.  Various logging bits truncate
11706            // things at 128k.
11707            needsFlush = (sb.length() > 64 * 1024);
11708        }
11709
11710        // Flush immediately if the buffer's grown too large, or this
11711        // is a non-system app.  Non-system apps are isolated with a
11712        // different tag & policy and not batched.
11713        //
11714        // Batching is useful during internal testing with
11715        // StrictMode settings turned up high.  Without batching,
11716        // thousands of separate files could be created on boot.
11717        if (!isSystemApp || needsFlush) {
11718            new Thread("Error dump: " + dropboxTag) {
11719                @Override
11720                public void run() {
11721                    String report;
11722                    synchronized (sb) {
11723                        report = sb.toString();
11724                        sb.delete(0, sb.length());
11725                        sb.trimToSize();
11726                    }
11727                    if (report.length() != 0) {
11728                        dbox.addText(dropboxTag, report);
11729                    }
11730                }
11731            }.start();
11732            return;
11733        }
11734
11735        // System app batching:
11736        if (!bufferWasEmpty) {
11737            // An existing dropbox-writing thread is outstanding, so
11738            // we don't need to start it up.  The existing thread will
11739            // catch the buffer appends we just did.
11740            return;
11741        }
11742
11743        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11744        // (After this point, we shouldn't access AMS internal data structures.)
11745        new Thread("Error dump: " + dropboxTag) {
11746            @Override
11747            public void run() {
11748                // 5 second sleep to let stacks arrive and be batched together
11749                try {
11750                    Thread.sleep(5000);  // 5 seconds
11751                } catch (InterruptedException e) {}
11752
11753                String errorReport;
11754                synchronized (mStrictModeBuffer) {
11755                    errorReport = mStrictModeBuffer.toString();
11756                    if (errorReport.length() == 0) {
11757                        return;
11758                    }
11759                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11760                    mStrictModeBuffer.trimToSize();
11761                }
11762                dbox.addText(dropboxTag, errorReport);
11763            }
11764        }.start();
11765    }
11766
11767    /**
11768     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11769     * @param app object of the crashing app, null for the system server
11770     * @param tag reported by the caller
11771     * @param system whether this wtf is coming from the system
11772     * @param crashInfo describing the context of the error
11773     * @return true if the process should exit immediately (WTF is fatal)
11774     */
11775    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11776            final ApplicationErrorReport.CrashInfo crashInfo) {
11777        final int callingUid = Binder.getCallingUid();
11778        final int callingPid = Binder.getCallingPid();
11779
11780        if (system) {
11781            // If this is coming from the system, we could very well have low-level
11782            // system locks held, so we want to do this all asynchronously.  And we
11783            // never want this to become fatal, so there is that too.
11784            mHandler.post(new Runnable() {
11785                @Override public void run() {
11786                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11787                }
11788            });
11789            return false;
11790        }
11791
11792        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11793                crashInfo);
11794
11795        if (r != null && r.pid != Process.myPid() &&
11796                Settings.Global.getInt(mContext.getContentResolver(),
11797                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11798            crashApplication(r, crashInfo);
11799            return true;
11800        } else {
11801            return false;
11802        }
11803    }
11804
11805    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11806            final ApplicationErrorReport.CrashInfo crashInfo) {
11807        final ProcessRecord r = findAppProcess(app, "WTF");
11808        final String processName = app == null ? "system_server"
11809                : (r == null ? "unknown" : r.processName);
11810
11811        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11812                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11813
11814        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11815
11816        return r;
11817    }
11818
11819    /**
11820     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11821     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11822     */
11823    private ProcessRecord findAppProcess(IBinder app, String reason) {
11824        if (app == null) {
11825            return null;
11826        }
11827
11828        synchronized (this) {
11829            final int NP = mProcessNames.getMap().size();
11830            for (int ip=0; ip<NP; ip++) {
11831                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11832                final int NA = apps.size();
11833                for (int ia=0; ia<NA; ia++) {
11834                    ProcessRecord p = apps.valueAt(ia);
11835                    if (p.thread != null && p.thread.asBinder() == app) {
11836                        return p;
11837                    }
11838                }
11839            }
11840
11841            Slog.w(TAG, "Can't find mystery application for " + reason
11842                    + " from pid=" + Binder.getCallingPid()
11843                    + " uid=" + Binder.getCallingUid() + ": " + app);
11844            return null;
11845        }
11846    }
11847
11848    /**
11849     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11850     * to append various headers to the dropbox log text.
11851     */
11852    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11853            StringBuilder sb) {
11854        // Watchdog thread ends up invoking this function (with
11855        // a null ProcessRecord) to add the stack file to dropbox.
11856        // Do not acquire a lock on this (am) in such cases, as it
11857        // could cause a potential deadlock, if and when watchdog
11858        // is invoked due to unavailability of lock on am and it
11859        // would prevent watchdog from killing system_server.
11860        if (process == null) {
11861            sb.append("Process: ").append(processName).append("\n");
11862            return;
11863        }
11864        // Note: ProcessRecord 'process' is guarded by the service
11865        // instance.  (notably process.pkgList, which could otherwise change
11866        // concurrently during execution of this method)
11867        synchronized (this) {
11868            sb.append("Process: ").append(processName).append("\n");
11869            int flags = process.info.flags;
11870            IPackageManager pm = AppGlobals.getPackageManager();
11871            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11872            for (int ip=0; ip<process.pkgList.size(); ip++) {
11873                String pkg = process.pkgList.keyAt(ip);
11874                sb.append("Package: ").append(pkg);
11875                try {
11876                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11877                    if (pi != null) {
11878                        sb.append(" v").append(pi.versionCode);
11879                        if (pi.versionName != null) {
11880                            sb.append(" (").append(pi.versionName).append(")");
11881                        }
11882                    }
11883                } catch (RemoteException e) {
11884                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11885                }
11886                sb.append("\n");
11887            }
11888        }
11889    }
11890
11891    private static String processClass(ProcessRecord process) {
11892        if (process == null || process.pid == MY_PID) {
11893            return "system_server";
11894        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11895            return "system_app";
11896        } else {
11897            return "data_app";
11898        }
11899    }
11900
11901    /**
11902     * Write a description of an error (crash, WTF, ANR) to the drop box.
11903     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11904     * @param process which caused the error, null means the system server
11905     * @param activity which triggered the error, null if unknown
11906     * @param parent activity related to the error, null if unknown
11907     * @param subject line related to the error, null if absent
11908     * @param report in long form describing the error, null if absent
11909     * @param logFile to include in the report, null if none
11910     * @param crashInfo giving an application stack trace, null if absent
11911     */
11912    public void addErrorToDropBox(String eventType,
11913            ProcessRecord process, String processName, ActivityRecord activity,
11914            ActivityRecord parent, String subject,
11915            final String report, final File logFile,
11916            final ApplicationErrorReport.CrashInfo crashInfo) {
11917        // NOTE -- this must never acquire the ActivityManagerService lock,
11918        // otherwise the watchdog may be prevented from resetting the system.
11919
11920        final String dropboxTag = processClass(process) + "_" + eventType;
11921        final DropBoxManager dbox = (DropBoxManager)
11922                mContext.getSystemService(Context.DROPBOX_SERVICE);
11923
11924        // Exit early if the dropbox isn't configured to accept this report type.
11925        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11926
11927        final StringBuilder sb = new StringBuilder(1024);
11928        appendDropBoxProcessHeaders(process, processName, sb);
11929        if (activity != null) {
11930            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11931        }
11932        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11933            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11934        }
11935        if (parent != null && parent != activity) {
11936            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11937        }
11938        if (subject != null) {
11939            sb.append("Subject: ").append(subject).append("\n");
11940        }
11941        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11942        if (Debug.isDebuggerConnected()) {
11943            sb.append("Debugger: Connected\n");
11944        }
11945        sb.append("\n");
11946
11947        // Do the rest in a worker thread to avoid blocking the caller on I/O
11948        // (After this point, we shouldn't access AMS internal data structures.)
11949        Thread worker = new Thread("Error dump: " + dropboxTag) {
11950            @Override
11951            public void run() {
11952                if (report != null) {
11953                    sb.append(report);
11954                }
11955                if (logFile != null) {
11956                    try {
11957                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11958                                    "\n\n[[TRUNCATED]]"));
11959                    } catch (IOException e) {
11960                        Slog.e(TAG, "Error reading " + logFile, e);
11961                    }
11962                }
11963                if (crashInfo != null && crashInfo.stackTrace != null) {
11964                    sb.append(crashInfo.stackTrace);
11965                }
11966
11967                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11968                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11969                if (lines > 0) {
11970                    sb.append("\n");
11971
11972                    // Merge several logcat streams, and take the last N lines
11973                    InputStreamReader input = null;
11974                    try {
11975                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11976                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11977                                "-b", "crash",
11978                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11979
11980                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11981                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11982                        input = new InputStreamReader(logcat.getInputStream());
11983
11984                        int num;
11985                        char[] buf = new char[8192];
11986                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11987                    } catch (IOException e) {
11988                        Slog.e(TAG, "Error running logcat", e);
11989                    } finally {
11990                        if (input != null) try { input.close(); } catch (IOException e) {}
11991                    }
11992                }
11993
11994                dbox.addText(dropboxTag, sb.toString());
11995            }
11996        };
11997
11998        if (process == null) {
11999            // If process is null, we are being called from some internal code
12000            // and may be about to die -- run this synchronously.
12001            worker.run();
12002        } else {
12003            worker.start();
12004        }
12005    }
12006
12007    /**
12008     * Bring up the "unexpected error" dialog box for a crashing app.
12009     * Deal with edge cases (intercepts from instrumented applications,
12010     * ActivityController, error intent receivers, that sort of thing).
12011     * @param r the application crashing
12012     * @param crashInfo describing the failure
12013     */
12014    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12015        long timeMillis = System.currentTimeMillis();
12016        String shortMsg = crashInfo.exceptionClassName;
12017        String longMsg = crashInfo.exceptionMessage;
12018        String stackTrace = crashInfo.stackTrace;
12019        if (shortMsg != null && longMsg != null) {
12020            longMsg = shortMsg + ": " + longMsg;
12021        } else if (shortMsg != null) {
12022            longMsg = shortMsg;
12023        }
12024
12025        AppErrorResult result = new AppErrorResult();
12026        synchronized (this) {
12027            if (mController != null) {
12028                try {
12029                    String name = r != null ? r.processName : null;
12030                    int pid = r != null ? r.pid : Binder.getCallingPid();
12031                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12032                    if (!mController.appCrashed(name, pid,
12033                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12034                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12035                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12036                            Slog.w(TAG, "Skip killing native crashed app " + name
12037                                    + "(" + pid + ") during testing");
12038                        } else {
12039                            Slog.w(TAG, "Force-killing crashed app " + name
12040                                    + " at watcher's request");
12041                            if (r != null) {
12042                                r.kill("crash", true);
12043                            } else {
12044                                // Huh.
12045                                Process.killProcess(pid);
12046                                Process.killProcessGroup(uid, pid);
12047                            }
12048                        }
12049                        return;
12050                    }
12051                } catch (RemoteException e) {
12052                    mController = null;
12053                    Watchdog.getInstance().setActivityController(null);
12054                }
12055            }
12056
12057            final long origId = Binder.clearCallingIdentity();
12058
12059            // If this process is running instrumentation, finish it.
12060            if (r != null && r.instrumentationClass != null) {
12061                Slog.w(TAG, "Error in app " + r.processName
12062                      + " running instrumentation " + r.instrumentationClass + ":");
12063                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12064                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12065                Bundle info = new Bundle();
12066                info.putString("shortMsg", shortMsg);
12067                info.putString("longMsg", longMsg);
12068                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12069                Binder.restoreCallingIdentity(origId);
12070                return;
12071            }
12072
12073            // Log crash in battery stats.
12074            if (r != null) {
12075                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12076            }
12077
12078            // If we can't identify the process or it's already exceeded its crash quota,
12079            // quit right away without showing a crash dialog.
12080            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12081                Binder.restoreCallingIdentity(origId);
12082                return;
12083            }
12084
12085            Message msg = Message.obtain();
12086            msg.what = SHOW_ERROR_MSG;
12087            HashMap data = new HashMap();
12088            data.put("result", result);
12089            data.put("app", r);
12090            msg.obj = data;
12091            mHandler.sendMessage(msg);
12092
12093            Binder.restoreCallingIdentity(origId);
12094        }
12095
12096        int res = result.get();
12097
12098        Intent appErrorIntent = null;
12099        synchronized (this) {
12100            if (r != null && !r.isolated) {
12101                // XXX Can't keep track of crash time for isolated processes,
12102                // since they don't have a persistent identity.
12103                mProcessCrashTimes.put(r.info.processName, r.uid,
12104                        SystemClock.uptimeMillis());
12105            }
12106            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12107                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12108            }
12109        }
12110
12111        if (appErrorIntent != null) {
12112            try {
12113                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12114            } catch (ActivityNotFoundException e) {
12115                Slog.w(TAG, "bug report receiver dissappeared", e);
12116            }
12117        }
12118    }
12119
12120    Intent createAppErrorIntentLocked(ProcessRecord r,
12121            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12122        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12123        if (report == null) {
12124            return null;
12125        }
12126        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12127        result.setComponent(r.errorReportReceiver);
12128        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12129        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12130        return result;
12131    }
12132
12133    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12134            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12135        if (r.errorReportReceiver == null) {
12136            return null;
12137        }
12138
12139        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12140            return null;
12141        }
12142
12143        ApplicationErrorReport report = new ApplicationErrorReport();
12144        report.packageName = r.info.packageName;
12145        report.installerPackageName = r.errorReportReceiver.getPackageName();
12146        report.processName = r.processName;
12147        report.time = timeMillis;
12148        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12149
12150        if (r.crashing || r.forceCrashReport) {
12151            report.type = ApplicationErrorReport.TYPE_CRASH;
12152            report.crashInfo = crashInfo;
12153        } else if (r.notResponding) {
12154            report.type = ApplicationErrorReport.TYPE_ANR;
12155            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12156
12157            report.anrInfo.activity = r.notRespondingReport.tag;
12158            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12159            report.anrInfo.info = r.notRespondingReport.longMsg;
12160        }
12161
12162        return report;
12163    }
12164
12165    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12166        enforceNotIsolatedCaller("getProcessesInErrorState");
12167        // assume our apps are happy - lazy create the list
12168        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12169
12170        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12171                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12172        int userId = UserHandle.getUserId(Binder.getCallingUid());
12173
12174        synchronized (this) {
12175
12176            // iterate across all processes
12177            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12178                ProcessRecord app = mLruProcesses.get(i);
12179                if (!allUsers && app.userId != userId) {
12180                    continue;
12181                }
12182                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12183                    // This one's in trouble, so we'll generate a report for it
12184                    // crashes are higher priority (in case there's a crash *and* an anr)
12185                    ActivityManager.ProcessErrorStateInfo report = null;
12186                    if (app.crashing) {
12187                        report = app.crashingReport;
12188                    } else if (app.notResponding) {
12189                        report = app.notRespondingReport;
12190                    }
12191
12192                    if (report != null) {
12193                        if (errList == null) {
12194                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12195                        }
12196                        errList.add(report);
12197                    } else {
12198                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12199                                " crashing = " + app.crashing +
12200                                " notResponding = " + app.notResponding);
12201                    }
12202                }
12203            }
12204        }
12205
12206        return errList;
12207    }
12208
12209    static int procStateToImportance(int procState, int memAdj,
12210            ActivityManager.RunningAppProcessInfo currApp) {
12211        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12212        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12213            currApp.lru = memAdj;
12214        } else {
12215            currApp.lru = 0;
12216        }
12217        return imp;
12218    }
12219
12220    private void fillInProcMemInfo(ProcessRecord app,
12221            ActivityManager.RunningAppProcessInfo outInfo) {
12222        outInfo.pid = app.pid;
12223        outInfo.uid = app.info.uid;
12224        if (mHeavyWeightProcess == app) {
12225            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12226        }
12227        if (app.persistent) {
12228            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12229        }
12230        if (app.activities.size() > 0) {
12231            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12232        }
12233        outInfo.lastTrimLevel = app.trimMemoryLevel;
12234        int adj = app.curAdj;
12235        int procState = app.curProcState;
12236        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12237        outInfo.importanceReasonCode = app.adjTypeCode;
12238        outInfo.processState = app.curProcState;
12239    }
12240
12241    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12242        enforceNotIsolatedCaller("getRunningAppProcesses");
12243        // Lazy instantiation of list
12244        List<ActivityManager.RunningAppProcessInfo> runList = null;
12245        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12246                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12247        int userId = UserHandle.getUserId(Binder.getCallingUid());
12248        synchronized (this) {
12249            // Iterate across all processes
12250            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12251                ProcessRecord app = mLruProcesses.get(i);
12252                if (!allUsers && app.userId != userId) {
12253                    continue;
12254                }
12255                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12256                    // Generate process state info for running application
12257                    ActivityManager.RunningAppProcessInfo currApp =
12258                        new ActivityManager.RunningAppProcessInfo(app.processName,
12259                                app.pid, app.getPackageList());
12260                    fillInProcMemInfo(app, currApp);
12261                    if (app.adjSource instanceof ProcessRecord) {
12262                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12263                        currApp.importanceReasonImportance =
12264                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12265                                        app.adjSourceProcState);
12266                    } else if (app.adjSource instanceof ActivityRecord) {
12267                        ActivityRecord r = (ActivityRecord)app.adjSource;
12268                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12269                    }
12270                    if (app.adjTarget instanceof ComponentName) {
12271                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12272                    }
12273                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12274                    //        + " lru=" + currApp.lru);
12275                    if (runList == null) {
12276                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12277                    }
12278                    runList.add(currApp);
12279                }
12280            }
12281        }
12282        return runList;
12283    }
12284
12285    public List<ApplicationInfo> getRunningExternalApplications() {
12286        enforceNotIsolatedCaller("getRunningExternalApplications");
12287        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12288        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12289        if (runningApps != null && runningApps.size() > 0) {
12290            Set<String> extList = new HashSet<String>();
12291            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12292                if (app.pkgList != null) {
12293                    for (String pkg : app.pkgList) {
12294                        extList.add(pkg);
12295                    }
12296                }
12297            }
12298            IPackageManager pm = AppGlobals.getPackageManager();
12299            for (String pkg : extList) {
12300                try {
12301                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12302                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12303                        retList.add(info);
12304                    }
12305                } catch (RemoteException e) {
12306                }
12307            }
12308        }
12309        return retList;
12310    }
12311
12312    @Override
12313    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12314        enforceNotIsolatedCaller("getMyMemoryState");
12315        synchronized (this) {
12316            ProcessRecord proc;
12317            synchronized (mPidsSelfLocked) {
12318                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12319            }
12320            fillInProcMemInfo(proc, outInfo);
12321        }
12322    }
12323
12324    @Override
12325    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12326        if (checkCallingPermission(android.Manifest.permission.DUMP)
12327                != PackageManager.PERMISSION_GRANTED) {
12328            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12329                    + Binder.getCallingPid()
12330                    + ", uid=" + Binder.getCallingUid()
12331                    + " without permission "
12332                    + android.Manifest.permission.DUMP);
12333            return;
12334        }
12335
12336        boolean dumpAll = false;
12337        boolean dumpClient = false;
12338        String dumpPackage = null;
12339
12340        int opti = 0;
12341        while (opti < args.length) {
12342            String opt = args[opti];
12343            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12344                break;
12345            }
12346            opti++;
12347            if ("-a".equals(opt)) {
12348                dumpAll = true;
12349            } else if ("-c".equals(opt)) {
12350                dumpClient = true;
12351            } else if ("-p".equals(opt)) {
12352                if (opti < args.length) {
12353                    dumpPackage = args[opti];
12354                    opti++;
12355                } else {
12356                    pw.println("Error: -p option requires package argument");
12357                    return;
12358                }
12359                dumpClient = true;
12360            } else if ("-h".equals(opt)) {
12361                pw.println("Activity manager dump options:");
12362                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12363                pw.println("  cmd may be one of:");
12364                pw.println("    a[ctivities]: activity stack state");
12365                pw.println("    r[recents]: recent activities state");
12366                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12367                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12368                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12369                pw.println("    o[om]: out of memory management");
12370                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12371                pw.println("    provider [COMP_SPEC]: provider client-side state");
12372                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12373                pw.println("    as[sociations]: tracked app associations");
12374                pw.println("    service [COMP_SPEC]: service client-side state");
12375                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12376                pw.println("    all: dump all activities");
12377                pw.println("    top: dump the top activity");
12378                pw.println("    write: write all pending state to storage");
12379                pw.println("    track-associations: enable association tracking");
12380                pw.println("    untrack-associations: disable and clear association tracking");
12381                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12382                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12383                pw.println("    a partial substring in a component name, a");
12384                pw.println("    hex object identifier.");
12385                pw.println("  -a: include all available server state.");
12386                pw.println("  -c: include client state.");
12387                pw.println("  -p: limit output to given package.");
12388                return;
12389            } else {
12390                pw.println("Unknown argument: " + opt + "; use -h for help");
12391            }
12392        }
12393
12394        long origId = Binder.clearCallingIdentity();
12395        boolean more = false;
12396        // Is the caller requesting to dump a particular piece of data?
12397        if (opti < args.length) {
12398            String cmd = args[opti];
12399            opti++;
12400            if ("activities".equals(cmd) || "a".equals(cmd)) {
12401                synchronized (this) {
12402                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12403                }
12404            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12405                synchronized (this) {
12406                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12407                }
12408            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12409                String[] newArgs;
12410                String name;
12411                if (opti >= args.length) {
12412                    name = null;
12413                    newArgs = EMPTY_STRING_ARRAY;
12414                } else {
12415                    dumpPackage = args[opti];
12416                    opti++;
12417                    newArgs = new String[args.length - opti];
12418                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12419                            args.length - opti);
12420                }
12421                synchronized (this) {
12422                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12423                }
12424            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12425                String[] newArgs;
12426                String name;
12427                if (opti >= args.length) {
12428                    name = null;
12429                    newArgs = EMPTY_STRING_ARRAY;
12430                } else {
12431                    dumpPackage = args[opti];
12432                    opti++;
12433                    newArgs = new String[args.length - opti];
12434                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12435                            args.length - opti);
12436                }
12437                synchronized (this) {
12438                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12439                }
12440            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12441                String[] newArgs;
12442                String name;
12443                if (opti >= args.length) {
12444                    name = null;
12445                    newArgs = EMPTY_STRING_ARRAY;
12446                } else {
12447                    dumpPackage = args[opti];
12448                    opti++;
12449                    newArgs = new String[args.length - opti];
12450                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12451                            args.length - opti);
12452                }
12453                synchronized (this) {
12454                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12455                }
12456            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12457                synchronized (this) {
12458                    dumpOomLocked(fd, pw, args, opti, true);
12459                }
12460            } else if ("provider".equals(cmd)) {
12461                String[] newArgs;
12462                String name;
12463                if (opti >= args.length) {
12464                    name = null;
12465                    newArgs = EMPTY_STRING_ARRAY;
12466                } else {
12467                    name = args[opti];
12468                    opti++;
12469                    newArgs = new String[args.length - opti];
12470                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12471                }
12472                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12473                    pw.println("No providers match: " + name);
12474                    pw.println("Use -h for help.");
12475                }
12476            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12477                synchronized (this) {
12478                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12479                }
12480            } else if ("service".equals(cmd)) {
12481                String[] newArgs;
12482                String name;
12483                if (opti >= args.length) {
12484                    name = null;
12485                    newArgs = EMPTY_STRING_ARRAY;
12486                } else {
12487                    name = args[opti];
12488                    opti++;
12489                    newArgs = new String[args.length - opti];
12490                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12491                            args.length - opti);
12492                }
12493                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12494                    pw.println("No services match: " + name);
12495                    pw.println("Use -h for help.");
12496                }
12497            } else if ("package".equals(cmd)) {
12498                String[] newArgs;
12499                if (opti >= args.length) {
12500                    pw.println("package: no package name specified");
12501                    pw.println("Use -h for help.");
12502                } else {
12503                    dumpPackage = args[opti];
12504                    opti++;
12505                    newArgs = new String[args.length - opti];
12506                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12507                            args.length - opti);
12508                    args = newArgs;
12509                    opti = 0;
12510                    more = true;
12511                }
12512            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12513                synchronized (this) {
12514                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12515                }
12516            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12517                synchronized (this) {
12518                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12519                }
12520            } else if ("write".equals(cmd)) {
12521                mTaskPersister.flush();
12522                pw.println("All tasks persisted.");
12523                return;
12524            } else if ("track-associations".equals(cmd)) {
12525                synchronized (this) {
12526                    if (!mTrackingAssociations) {
12527                        mTrackingAssociations = true;
12528                        pw.println("Association tracking started.");
12529                    } else {
12530                        pw.println("Association tracking already enabled.");
12531                    }
12532                }
12533                return;
12534            } else if ("untrack-associations".equals(cmd)) {
12535                synchronized (this) {
12536                    if (mTrackingAssociations) {
12537                        mTrackingAssociations = false;
12538                        mAssociations.clear();
12539                        pw.println("Association tracking stopped.");
12540                    } else {
12541                        pw.println("Association tracking not running.");
12542                    }
12543                }
12544                return;
12545            } else {
12546                // Dumping a single activity?
12547                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12548                    pw.println("Bad activity command, or no activities match: " + cmd);
12549                    pw.println("Use -h for help.");
12550                }
12551            }
12552            if (!more) {
12553                Binder.restoreCallingIdentity(origId);
12554                return;
12555            }
12556        }
12557
12558        // No piece of data specified, dump everything.
12559        synchronized (this) {
12560            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12561            pw.println();
12562            if (dumpAll) {
12563                pw.println("-------------------------------------------------------------------------------");
12564            }
12565            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12566            pw.println();
12567            if (dumpAll) {
12568                pw.println("-------------------------------------------------------------------------------");
12569            }
12570            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12571            pw.println();
12572            if (dumpAll) {
12573                pw.println("-------------------------------------------------------------------------------");
12574            }
12575            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12576            pw.println();
12577            if (dumpAll) {
12578                pw.println("-------------------------------------------------------------------------------");
12579            }
12580            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12581            pw.println();
12582            if (dumpAll) {
12583                pw.println("-------------------------------------------------------------------------------");
12584            }
12585            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12586            if (mAssociations.size() > 0) {
12587                pw.println();
12588                if (dumpAll) {
12589                    pw.println("-------------------------------------------------------------------------------");
12590                }
12591                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12592            }
12593            pw.println();
12594            if (dumpAll) {
12595                pw.println("-------------------------------------------------------------------------------");
12596            }
12597            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12598        }
12599        Binder.restoreCallingIdentity(origId);
12600    }
12601
12602    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12603            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12604        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12605
12606        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12607                dumpPackage);
12608        boolean needSep = printedAnything;
12609
12610        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12611                dumpPackage, needSep, "  mFocusedActivity: ");
12612        if (printed) {
12613            printedAnything = true;
12614            needSep = false;
12615        }
12616
12617        if (dumpPackage == null) {
12618            if (needSep) {
12619                pw.println();
12620            }
12621            needSep = true;
12622            printedAnything = true;
12623            mStackSupervisor.dump(pw, "  ");
12624        }
12625
12626        if (!printedAnything) {
12627            pw.println("  (nothing)");
12628        }
12629    }
12630
12631    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12632            int opti, boolean dumpAll, String dumpPackage) {
12633        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12634
12635        boolean printedAnything = false;
12636
12637        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12638            boolean printedHeader = false;
12639
12640            final int N = mRecentTasks.size();
12641            for (int i=0; i<N; i++) {
12642                TaskRecord tr = mRecentTasks.get(i);
12643                if (dumpPackage != null) {
12644                    if (tr.realActivity == null ||
12645                            !dumpPackage.equals(tr.realActivity)) {
12646                        continue;
12647                    }
12648                }
12649                if (!printedHeader) {
12650                    pw.println("  Recent tasks:");
12651                    printedHeader = true;
12652                    printedAnything = true;
12653                }
12654                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12655                        pw.println(tr);
12656                if (dumpAll) {
12657                    mRecentTasks.get(i).dump(pw, "    ");
12658                }
12659            }
12660        }
12661
12662        if (!printedAnything) {
12663            pw.println("  (nothing)");
12664        }
12665    }
12666
12667    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12668            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12669        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12670
12671        int dumpUid = 0;
12672        if (dumpPackage != null) {
12673            IPackageManager pm = AppGlobals.getPackageManager();
12674            try {
12675                dumpUid = pm.getPackageUid(dumpPackage, 0);
12676            } catch (RemoteException e) {
12677            }
12678        }
12679
12680        boolean printedAnything = false;
12681
12682        final long now = SystemClock.uptimeMillis();
12683
12684        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12685            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12686                    = mAssociations.valueAt(i1);
12687            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12688                SparseArray<ArrayMap<String, Association>> sourceUids
12689                        = targetComponents.valueAt(i2);
12690                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12691                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12692                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12693                        Association ass = sourceProcesses.valueAt(i4);
12694                        if (dumpPackage != null) {
12695                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12696                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12697                                continue;
12698                            }
12699                        }
12700                        printedAnything = true;
12701                        pw.print("  ");
12702                        pw.print(ass.mTargetProcess);
12703                        pw.print("/");
12704                        UserHandle.formatUid(pw, ass.mTargetUid);
12705                        pw.print(" <- ");
12706                        pw.print(ass.mSourceProcess);
12707                        pw.print("/");
12708                        UserHandle.formatUid(pw, ass.mSourceUid);
12709                        pw.println();
12710                        pw.print("    via ");
12711                        pw.print(ass.mTargetComponent.flattenToShortString());
12712                        pw.println();
12713                        pw.print("    ");
12714                        long dur = ass.mTime;
12715                        if (ass.mNesting > 0) {
12716                            dur += now - ass.mStartTime;
12717                        }
12718                        TimeUtils.formatDuration(dur, pw);
12719                        pw.print(" (");
12720                        pw.print(ass.mCount);
12721                        pw.println(" times)");
12722                        if (ass.mNesting > 0) {
12723                            pw.print("    ");
12724                            pw.print(" Currently active: ");
12725                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12726                            pw.println();
12727                        }
12728                    }
12729                }
12730            }
12731
12732        }
12733
12734        if (!printedAnything) {
12735            pw.println("  (nothing)");
12736        }
12737    }
12738
12739    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12740            int opti, boolean dumpAll, String dumpPackage) {
12741        boolean needSep = false;
12742        boolean printedAnything = false;
12743        int numPers = 0;
12744
12745        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12746
12747        if (dumpAll) {
12748            final int NP = mProcessNames.getMap().size();
12749            for (int ip=0; ip<NP; ip++) {
12750                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12751                final int NA = procs.size();
12752                for (int ia=0; ia<NA; ia++) {
12753                    ProcessRecord r = procs.valueAt(ia);
12754                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12755                        continue;
12756                    }
12757                    if (!needSep) {
12758                        pw.println("  All known processes:");
12759                        needSep = true;
12760                        printedAnything = true;
12761                    }
12762                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12763                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12764                        pw.print(" "); pw.println(r);
12765                    r.dump(pw, "    ");
12766                    if (r.persistent) {
12767                        numPers++;
12768                    }
12769                }
12770            }
12771        }
12772
12773        if (mIsolatedProcesses.size() > 0) {
12774            boolean printed = false;
12775            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12776                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12777                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12778                    continue;
12779                }
12780                if (!printed) {
12781                    if (needSep) {
12782                        pw.println();
12783                    }
12784                    pw.println("  Isolated process list (sorted by uid):");
12785                    printedAnything = true;
12786                    printed = true;
12787                    needSep = true;
12788                }
12789                pw.println(String.format("%sIsolated #%2d: %s",
12790                        "    ", i, r.toString()));
12791            }
12792        }
12793
12794        if (mLruProcesses.size() > 0) {
12795            if (needSep) {
12796                pw.println();
12797            }
12798            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12799                    pw.print(" total, non-act at ");
12800                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12801                    pw.print(", non-svc at ");
12802                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12803                    pw.println("):");
12804            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12805            needSep = true;
12806            printedAnything = true;
12807        }
12808
12809        if (dumpAll || dumpPackage != null) {
12810            synchronized (mPidsSelfLocked) {
12811                boolean printed = false;
12812                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12813                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12814                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12815                        continue;
12816                    }
12817                    if (!printed) {
12818                        if (needSep) pw.println();
12819                        needSep = true;
12820                        pw.println("  PID mappings:");
12821                        printed = true;
12822                        printedAnything = true;
12823                    }
12824                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12825                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12826                }
12827            }
12828        }
12829
12830        if (mForegroundProcesses.size() > 0) {
12831            synchronized (mPidsSelfLocked) {
12832                boolean printed = false;
12833                for (int i=0; i<mForegroundProcesses.size(); i++) {
12834                    ProcessRecord r = mPidsSelfLocked.get(
12835                            mForegroundProcesses.valueAt(i).pid);
12836                    if (dumpPackage != null && (r == null
12837                            || !r.pkgList.containsKey(dumpPackage))) {
12838                        continue;
12839                    }
12840                    if (!printed) {
12841                        if (needSep) pw.println();
12842                        needSep = true;
12843                        pw.println("  Foreground Processes:");
12844                        printed = true;
12845                        printedAnything = true;
12846                    }
12847                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12848                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12849                }
12850            }
12851        }
12852
12853        if (mPersistentStartingProcesses.size() > 0) {
12854            if (needSep) pw.println();
12855            needSep = true;
12856            printedAnything = true;
12857            pw.println("  Persisent processes that are starting:");
12858            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12859                    "Starting Norm", "Restarting PERS", dumpPackage);
12860        }
12861
12862        if (mRemovedProcesses.size() > 0) {
12863            if (needSep) pw.println();
12864            needSep = true;
12865            printedAnything = true;
12866            pw.println("  Processes that are being removed:");
12867            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12868                    "Removed Norm", "Removed PERS", dumpPackage);
12869        }
12870
12871        if (mProcessesOnHold.size() > 0) {
12872            if (needSep) pw.println();
12873            needSep = true;
12874            printedAnything = true;
12875            pw.println("  Processes that are on old until the system is ready:");
12876            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12877                    "OnHold Norm", "OnHold PERS", dumpPackage);
12878        }
12879
12880        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12881
12882        if (mProcessCrashTimes.getMap().size() > 0) {
12883            boolean printed = false;
12884            long now = SystemClock.uptimeMillis();
12885            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12886            final int NP = pmap.size();
12887            for (int ip=0; ip<NP; ip++) {
12888                String pname = pmap.keyAt(ip);
12889                SparseArray<Long> uids = pmap.valueAt(ip);
12890                final int N = uids.size();
12891                for (int i=0; i<N; i++) {
12892                    int puid = uids.keyAt(i);
12893                    ProcessRecord r = mProcessNames.get(pname, puid);
12894                    if (dumpPackage != null && (r == null
12895                            || !r.pkgList.containsKey(dumpPackage))) {
12896                        continue;
12897                    }
12898                    if (!printed) {
12899                        if (needSep) pw.println();
12900                        needSep = true;
12901                        pw.println("  Time since processes crashed:");
12902                        printed = true;
12903                        printedAnything = true;
12904                    }
12905                    pw.print("    Process "); pw.print(pname);
12906                            pw.print(" uid "); pw.print(puid);
12907                            pw.print(": last crashed ");
12908                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12909                            pw.println(" ago");
12910                }
12911            }
12912        }
12913
12914        if (mBadProcesses.getMap().size() > 0) {
12915            boolean printed = false;
12916            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12917            final int NP = pmap.size();
12918            for (int ip=0; ip<NP; ip++) {
12919                String pname = pmap.keyAt(ip);
12920                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12921                final int N = uids.size();
12922                for (int i=0; i<N; i++) {
12923                    int puid = uids.keyAt(i);
12924                    ProcessRecord r = mProcessNames.get(pname, puid);
12925                    if (dumpPackage != null && (r == null
12926                            || !r.pkgList.containsKey(dumpPackage))) {
12927                        continue;
12928                    }
12929                    if (!printed) {
12930                        if (needSep) pw.println();
12931                        needSep = true;
12932                        pw.println("  Bad processes:");
12933                        printedAnything = true;
12934                    }
12935                    BadProcessInfo info = uids.valueAt(i);
12936                    pw.print("    Bad process "); pw.print(pname);
12937                            pw.print(" uid "); pw.print(puid);
12938                            pw.print(": crashed at time "); pw.println(info.time);
12939                    if (info.shortMsg != null) {
12940                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12941                    }
12942                    if (info.longMsg != null) {
12943                        pw.print("      Long msg: "); pw.println(info.longMsg);
12944                    }
12945                    if (info.stack != null) {
12946                        pw.println("      Stack:");
12947                        int lastPos = 0;
12948                        for (int pos=0; pos<info.stack.length(); pos++) {
12949                            if (info.stack.charAt(pos) == '\n') {
12950                                pw.print("        ");
12951                                pw.write(info.stack, lastPos, pos-lastPos);
12952                                pw.println();
12953                                lastPos = pos+1;
12954                            }
12955                        }
12956                        if (lastPos < info.stack.length()) {
12957                            pw.print("        ");
12958                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12959                            pw.println();
12960                        }
12961                    }
12962                }
12963            }
12964        }
12965
12966        if (dumpPackage == null) {
12967            pw.println();
12968            needSep = false;
12969            pw.println("  mStartedUsers:");
12970            for (int i=0; i<mStartedUsers.size(); i++) {
12971                UserStartedState uss = mStartedUsers.valueAt(i);
12972                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12973                        pw.print(": "); uss.dump("", pw);
12974            }
12975            pw.print("  mStartedUserArray: [");
12976            for (int i=0; i<mStartedUserArray.length; i++) {
12977                if (i > 0) pw.print(", ");
12978                pw.print(mStartedUserArray[i]);
12979            }
12980            pw.println("]");
12981            pw.print("  mUserLru: [");
12982            for (int i=0; i<mUserLru.size(); i++) {
12983                if (i > 0) pw.print(", ");
12984                pw.print(mUserLru.get(i));
12985            }
12986            pw.println("]");
12987            if (dumpAll) {
12988                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12989            }
12990            synchronized (mUserProfileGroupIdsSelfLocked) {
12991                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12992                    pw.println("  mUserProfileGroupIds:");
12993                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12994                        pw.print("    User #");
12995                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12996                        pw.print(" -> profile #");
12997                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12998                    }
12999                }
13000            }
13001        }
13002        if (mHomeProcess != null && (dumpPackage == null
13003                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13004            if (needSep) {
13005                pw.println();
13006                needSep = false;
13007            }
13008            pw.println("  mHomeProcess: " + mHomeProcess);
13009        }
13010        if (mPreviousProcess != null && (dumpPackage == null
13011                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13012            if (needSep) {
13013                pw.println();
13014                needSep = false;
13015            }
13016            pw.println("  mPreviousProcess: " + mPreviousProcess);
13017        }
13018        if (dumpAll) {
13019            StringBuilder sb = new StringBuilder(128);
13020            sb.append("  mPreviousProcessVisibleTime: ");
13021            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13022            pw.println(sb);
13023        }
13024        if (mHeavyWeightProcess != null && (dumpPackage == null
13025                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13026            if (needSep) {
13027                pw.println();
13028                needSep = false;
13029            }
13030            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13031        }
13032        if (dumpPackage == null) {
13033            pw.println("  mConfiguration: " + mConfiguration);
13034        }
13035        if (dumpAll) {
13036            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13037            if (mCompatModePackages.getPackages().size() > 0) {
13038                boolean printed = false;
13039                for (Map.Entry<String, Integer> entry
13040                        : mCompatModePackages.getPackages().entrySet()) {
13041                    String pkg = entry.getKey();
13042                    int mode = entry.getValue();
13043                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13044                        continue;
13045                    }
13046                    if (!printed) {
13047                        pw.println("  mScreenCompatPackages:");
13048                        printed = true;
13049                    }
13050                    pw.print("    "); pw.print(pkg); pw.print(": ");
13051                            pw.print(mode); pw.println();
13052                }
13053            }
13054        }
13055        if (dumpPackage == null) {
13056            pw.println("  mWakefulness="
13057                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13058            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13059                    + lockScreenShownToString());
13060            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13061                    + " mTestPssMode=" + mTestPssMode);
13062        }
13063        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13064                || mOrigWaitForDebugger) {
13065            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13066                    || dumpPackage.equals(mOrigDebugApp)) {
13067                if (needSep) {
13068                    pw.println();
13069                    needSep = false;
13070                }
13071                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13072                        + " mDebugTransient=" + mDebugTransient
13073                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13074            }
13075        }
13076        if (mOpenGlTraceApp != null) {
13077            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13078                if (needSep) {
13079                    pw.println();
13080                    needSep = false;
13081                }
13082                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13083            }
13084        }
13085        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13086                || mProfileFd != null) {
13087            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13088                if (needSep) {
13089                    pw.println();
13090                    needSep = false;
13091                }
13092                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13093                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13094                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13095                        + mAutoStopProfiler);
13096                pw.println("  mProfileType=" + mProfileType);
13097            }
13098        }
13099        if (dumpPackage == null) {
13100            if (mAlwaysFinishActivities || mController != null) {
13101                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13102                        + " mController=" + mController);
13103            }
13104            if (dumpAll) {
13105                pw.println("  Total persistent processes: " + numPers);
13106                pw.println("  mProcessesReady=" + mProcessesReady
13107                        + " mSystemReady=" + mSystemReady
13108                        + " mBooted=" + mBooted
13109                        + " mFactoryTest=" + mFactoryTest);
13110                pw.println("  mBooting=" + mBooting
13111                        + " mCallFinishBooting=" + mCallFinishBooting
13112                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13113                pw.print("  mLastPowerCheckRealtime=");
13114                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13115                        pw.println("");
13116                pw.print("  mLastPowerCheckUptime=");
13117                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13118                        pw.println("");
13119                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13120                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13121                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13122                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13123                        + " (" + mLruProcesses.size() + " total)"
13124                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13125                        + " mNumServiceProcs=" + mNumServiceProcs
13126                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13127                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13128                        + " mLastMemoryLevel" + mLastMemoryLevel
13129                        + " mLastNumProcesses" + mLastNumProcesses);
13130                long now = SystemClock.uptimeMillis();
13131                pw.print("  mLastIdleTime=");
13132                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13133                        pw.print(" mLowRamSinceLastIdle=");
13134                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13135                        pw.println();
13136            }
13137        }
13138
13139        if (!printedAnything) {
13140            pw.println("  (nothing)");
13141        }
13142    }
13143
13144    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13145            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13146        if (mProcessesToGc.size() > 0) {
13147            boolean printed = false;
13148            long now = SystemClock.uptimeMillis();
13149            for (int i=0; i<mProcessesToGc.size(); i++) {
13150                ProcessRecord proc = mProcessesToGc.get(i);
13151                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13152                    continue;
13153                }
13154                if (!printed) {
13155                    if (needSep) pw.println();
13156                    needSep = true;
13157                    pw.println("  Processes that are waiting to GC:");
13158                    printed = true;
13159                }
13160                pw.print("    Process "); pw.println(proc);
13161                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13162                        pw.print(", last gced=");
13163                        pw.print(now-proc.lastRequestedGc);
13164                        pw.print(" ms ago, last lowMem=");
13165                        pw.print(now-proc.lastLowMemory);
13166                        pw.println(" ms ago");
13167
13168            }
13169        }
13170        return needSep;
13171    }
13172
13173    void printOomLevel(PrintWriter pw, String name, int adj) {
13174        pw.print("    ");
13175        if (adj >= 0) {
13176            pw.print(' ');
13177            if (adj < 10) pw.print(' ');
13178        } else {
13179            if (adj > -10) pw.print(' ');
13180        }
13181        pw.print(adj);
13182        pw.print(": ");
13183        pw.print(name);
13184        pw.print(" (");
13185        pw.print(mProcessList.getMemLevel(adj)/1024);
13186        pw.println(" kB)");
13187    }
13188
13189    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13190            int opti, boolean dumpAll) {
13191        boolean needSep = false;
13192
13193        if (mLruProcesses.size() > 0) {
13194            if (needSep) pw.println();
13195            needSep = true;
13196            pw.println("  OOM levels:");
13197            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13198            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13199            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13200            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13201            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13202            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13203            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13204            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13205            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13206            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13207            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13208            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13209            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13210            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13211
13212            if (needSep) pw.println();
13213            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13214                    pw.print(" total, non-act at ");
13215                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13216                    pw.print(", non-svc at ");
13217                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13218                    pw.println("):");
13219            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13220            needSep = true;
13221        }
13222
13223        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13224
13225        pw.println();
13226        pw.println("  mHomeProcess: " + mHomeProcess);
13227        pw.println("  mPreviousProcess: " + mPreviousProcess);
13228        if (mHeavyWeightProcess != null) {
13229            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13230        }
13231
13232        return true;
13233    }
13234
13235    /**
13236     * There are three ways to call this:
13237     *  - no provider specified: dump all the providers
13238     *  - a flattened component name that matched an existing provider was specified as the
13239     *    first arg: dump that one provider
13240     *  - the first arg isn't the flattened component name of an existing provider:
13241     *    dump all providers whose component contains the first arg as a substring
13242     */
13243    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13244            int opti, boolean dumpAll) {
13245        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13246    }
13247
13248    static class ItemMatcher {
13249        ArrayList<ComponentName> components;
13250        ArrayList<String> strings;
13251        ArrayList<Integer> objects;
13252        boolean all;
13253
13254        ItemMatcher() {
13255            all = true;
13256        }
13257
13258        void build(String name) {
13259            ComponentName componentName = ComponentName.unflattenFromString(name);
13260            if (componentName != null) {
13261                if (components == null) {
13262                    components = new ArrayList<ComponentName>();
13263                }
13264                components.add(componentName);
13265                all = false;
13266            } else {
13267                int objectId = 0;
13268                // Not a '/' separated full component name; maybe an object ID?
13269                try {
13270                    objectId = Integer.parseInt(name, 16);
13271                    if (objects == null) {
13272                        objects = new ArrayList<Integer>();
13273                    }
13274                    objects.add(objectId);
13275                    all = false;
13276                } catch (RuntimeException e) {
13277                    // Not an integer; just do string match.
13278                    if (strings == null) {
13279                        strings = new ArrayList<String>();
13280                    }
13281                    strings.add(name);
13282                    all = false;
13283                }
13284            }
13285        }
13286
13287        int build(String[] args, int opti) {
13288            for (; opti<args.length; opti++) {
13289                String name = args[opti];
13290                if ("--".equals(name)) {
13291                    return opti+1;
13292                }
13293                build(name);
13294            }
13295            return opti;
13296        }
13297
13298        boolean match(Object object, ComponentName comp) {
13299            if (all) {
13300                return true;
13301            }
13302            if (components != null) {
13303                for (int i=0; i<components.size(); i++) {
13304                    if (components.get(i).equals(comp)) {
13305                        return true;
13306                    }
13307                }
13308            }
13309            if (objects != null) {
13310                for (int i=0; i<objects.size(); i++) {
13311                    if (System.identityHashCode(object) == objects.get(i)) {
13312                        return true;
13313                    }
13314                }
13315            }
13316            if (strings != null) {
13317                String flat = comp.flattenToString();
13318                for (int i=0; i<strings.size(); i++) {
13319                    if (flat.contains(strings.get(i))) {
13320                        return true;
13321                    }
13322                }
13323            }
13324            return false;
13325        }
13326    }
13327
13328    /**
13329     * There are three things that cmd can be:
13330     *  - a flattened component name that matches an existing activity
13331     *  - the cmd arg isn't the flattened component name of an existing activity:
13332     *    dump all activity whose component contains the cmd as a substring
13333     *  - A hex number of the ActivityRecord object instance.
13334     */
13335    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13336            int opti, boolean dumpAll) {
13337        ArrayList<ActivityRecord> activities;
13338
13339        synchronized (this) {
13340            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13341        }
13342
13343        if (activities.size() <= 0) {
13344            return false;
13345        }
13346
13347        String[] newArgs = new String[args.length - opti];
13348        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13349
13350        TaskRecord lastTask = null;
13351        boolean needSep = false;
13352        for (int i=activities.size()-1; i>=0; i--) {
13353            ActivityRecord r = activities.get(i);
13354            if (needSep) {
13355                pw.println();
13356            }
13357            needSep = true;
13358            synchronized (this) {
13359                if (lastTask != r.task) {
13360                    lastTask = r.task;
13361                    pw.print("TASK "); pw.print(lastTask.affinity);
13362                            pw.print(" id="); pw.println(lastTask.taskId);
13363                    if (dumpAll) {
13364                        lastTask.dump(pw, "  ");
13365                    }
13366                }
13367            }
13368            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13369        }
13370        return true;
13371    }
13372
13373    /**
13374     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13375     * there is a thread associated with the activity.
13376     */
13377    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13378            final ActivityRecord r, String[] args, boolean dumpAll) {
13379        String innerPrefix = prefix + "  ";
13380        synchronized (this) {
13381            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13382                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13383                    pw.print(" pid=");
13384                    if (r.app != null) pw.println(r.app.pid);
13385                    else pw.println("(not running)");
13386            if (dumpAll) {
13387                r.dump(pw, innerPrefix);
13388            }
13389        }
13390        if (r.app != null && r.app.thread != null) {
13391            // flush anything that is already in the PrintWriter since the thread is going
13392            // to write to the file descriptor directly
13393            pw.flush();
13394            try {
13395                TransferPipe tp = new TransferPipe();
13396                try {
13397                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13398                            r.appToken, innerPrefix, args);
13399                    tp.go(fd);
13400                } finally {
13401                    tp.kill();
13402                }
13403            } catch (IOException e) {
13404                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13405            } catch (RemoteException e) {
13406                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13407            }
13408        }
13409    }
13410
13411    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13412            int opti, boolean dumpAll, String dumpPackage) {
13413        boolean needSep = false;
13414        boolean onlyHistory = false;
13415        boolean printedAnything = false;
13416
13417        if ("history".equals(dumpPackage)) {
13418            if (opti < args.length && "-s".equals(args[opti])) {
13419                dumpAll = false;
13420            }
13421            onlyHistory = true;
13422            dumpPackage = null;
13423        }
13424
13425        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13426        if (!onlyHistory && dumpAll) {
13427            if (mRegisteredReceivers.size() > 0) {
13428                boolean printed = false;
13429                Iterator it = mRegisteredReceivers.values().iterator();
13430                while (it.hasNext()) {
13431                    ReceiverList r = (ReceiverList)it.next();
13432                    if (dumpPackage != null && (r.app == null ||
13433                            !dumpPackage.equals(r.app.info.packageName))) {
13434                        continue;
13435                    }
13436                    if (!printed) {
13437                        pw.println("  Registered Receivers:");
13438                        needSep = true;
13439                        printed = true;
13440                        printedAnything = true;
13441                    }
13442                    pw.print("  * "); pw.println(r);
13443                    r.dump(pw, "    ");
13444                }
13445            }
13446
13447            if (mReceiverResolver.dump(pw, needSep ?
13448                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13449                    "    ", dumpPackage, false, false)) {
13450                needSep = true;
13451                printedAnything = true;
13452            }
13453        }
13454
13455        for (BroadcastQueue q : mBroadcastQueues) {
13456            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13457            printedAnything |= needSep;
13458        }
13459
13460        needSep = true;
13461
13462        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13463            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13464                if (needSep) {
13465                    pw.println();
13466                }
13467                needSep = true;
13468                printedAnything = true;
13469                pw.print("  Sticky broadcasts for user ");
13470                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13471                StringBuilder sb = new StringBuilder(128);
13472                for (Map.Entry<String, ArrayList<Intent>> ent
13473                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13474                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13475                    if (dumpAll) {
13476                        pw.println(":");
13477                        ArrayList<Intent> intents = ent.getValue();
13478                        final int N = intents.size();
13479                        for (int i=0; i<N; i++) {
13480                            sb.setLength(0);
13481                            sb.append("    Intent: ");
13482                            intents.get(i).toShortString(sb, false, true, false, false);
13483                            pw.println(sb.toString());
13484                            Bundle bundle = intents.get(i).getExtras();
13485                            if (bundle != null) {
13486                                pw.print("      ");
13487                                pw.println(bundle.toString());
13488                            }
13489                        }
13490                    } else {
13491                        pw.println("");
13492                    }
13493                }
13494            }
13495        }
13496
13497        if (!onlyHistory && dumpAll) {
13498            pw.println();
13499            for (BroadcastQueue queue : mBroadcastQueues) {
13500                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13501                        + queue.mBroadcastsScheduled);
13502            }
13503            pw.println("  mHandler:");
13504            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13505            needSep = true;
13506            printedAnything = true;
13507        }
13508
13509        if (!printedAnything) {
13510            pw.println("  (nothing)");
13511        }
13512    }
13513
13514    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13515            int opti, boolean dumpAll, String dumpPackage) {
13516        boolean needSep;
13517        boolean printedAnything = false;
13518
13519        ItemMatcher matcher = new ItemMatcher();
13520        matcher.build(args, opti);
13521
13522        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13523
13524        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13525        printedAnything |= needSep;
13526
13527        if (mLaunchingProviders.size() > 0) {
13528            boolean printed = false;
13529            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13530                ContentProviderRecord r = mLaunchingProviders.get(i);
13531                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13532                    continue;
13533                }
13534                if (!printed) {
13535                    if (needSep) pw.println();
13536                    needSep = true;
13537                    pw.println("  Launching content providers:");
13538                    printed = true;
13539                    printedAnything = true;
13540                }
13541                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13542                        pw.println(r);
13543            }
13544        }
13545
13546        if (mGrantedUriPermissions.size() > 0) {
13547            boolean printed = false;
13548            int dumpUid = -2;
13549            if (dumpPackage != null) {
13550                try {
13551                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13552                } catch (NameNotFoundException e) {
13553                    dumpUid = -1;
13554                }
13555            }
13556            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13557                int uid = mGrantedUriPermissions.keyAt(i);
13558                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13559                    continue;
13560                }
13561                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13562                if (!printed) {
13563                    if (needSep) pw.println();
13564                    needSep = true;
13565                    pw.println("  Granted Uri Permissions:");
13566                    printed = true;
13567                    printedAnything = true;
13568                }
13569                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13570                for (UriPermission perm : perms.values()) {
13571                    pw.print("    "); pw.println(perm);
13572                    if (dumpAll) {
13573                        perm.dump(pw, "      ");
13574                    }
13575                }
13576            }
13577        }
13578
13579        if (!printedAnything) {
13580            pw.println("  (nothing)");
13581        }
13582    }
13583
13584    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13585            int opti, boolean dumpAll, String dumpPackage) {
13586        boolean printed = false;
13587
13588        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13589
13590        if (mIntentSenderRecords.size() > 0) {
13591            Iterator<WeakReference<PendingIntentRecord>> it
13592                    = mIntentSenderRecords.values().iterator();
13593            while (it.hasNext()) {
13594                WeakReference<PendingIntentRecord> ref = it.next();
13595                PendingIntentRecord rec = ref != null ? ref.get(): null;
13596                if (dumpPackage != null && (rec == null
13597                        || !dumpPackage.equals(rec.key.packageName))) {
13598                    continue;
13599                }
13600                printed = true;
13601                if (rec != null) {
13602                    pw.print("  * "); pw.println(rec);
13603                    if (dumpAll) {
13604                        rec.dump(pw, "    ");
13605                    }
13606                } else {
13607                    pw.print("  * "); pw.println(ref);
13608                }
13609            }
13610        }
13611
13612        if (!printed) {
13613            pw.println("  (nothing)");
13614        }
13615    }
13616
13617    private static final int dumpProcessList(PrintWriter pw,
13618            ActivityManagerService service, List list,
13619            String prefix, String normalLabel, String persistentLabel,
13620            String dumpPackage) {
13621        int numPers = 0;
13622        final int N = list.size()-1;
13623        for (int i=N; i>=0; i--) {
13624            ProcessRecord r = (ProcessRecord)list.get(i);
13625            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13626                continue;
13627            }
13628            pw.println(String.format("%s%s #%2d: %s",
13629                    prefix, (r.persistent ? persistentLabel : normalLabel),
13630                    i, r.toString()));
13631            if (r.persistent) {
13632                numPers++;
13633            }
13634        }
13635        return numPers;
13636    }
13637
13638    private static final boolean dumpProcessOomList(PrintWriter pw,
13639            ActivityManagerService service, List<ProcessRecord> origList,
13640            String prefix, String normalLabel, String persistentLabel,
13641            boolean inclDetails, String dumpPackage) {
13642
13643        ArrayList<Pair<ProcessRecord, Integer>> list
13644                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13645        for (int i=0; i<origList.size(); i++) {
13646            ProcessRecord r = origList.get(i);
13647            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13648                continue;
13649            }
13650            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13651        }
13652
13653        if (list.size() <= 0) {
13654            return false;
13655        }
13656
13657        Comparator<Pair<ProcessRecord, Integer>> comparator
13658                = new Comparator<Pair<ProcessRecord, Integer>>() {
13659            @Override
13660            public int compare(Pair<ProcessRecord, Integer> object1,
13661                    Pair<ProcessRecord, Integer> object2) {
13662                if (object1.first.setAdj != object2.first.setAdj) {
13663                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13664                }
13665                if (object1.second.intValue() != object2.second.intValue()) {
13666                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13667                }
13668                return 0;
13669            }
13670        };
13671
13672        Collections.sort(list, comparator);
13673
13674        final long curRealtime = SystemClock.elapsedRealtime();
13675        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13676        final long curUptime = SystemClock.uptimeMillis();
13677        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13678
13679        for (int i=list.size()-1; i>=0; i--) {
13680            ProcessRecord r = list.get(i).first;
13681            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13682            char schedGroup;
13683            switch (r.setSchedGroup) {
13684                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13685                    schedGroup = 'B';
13686                    break;
13687                case Process.THREAD_GROUP_DEFAULT:
13688                    schedGroup = 'F';
13689                    break;
13690                default:
13691                    schedGroup = '?';
13692                    break;
13693            }
13694            char foreground;
13695            if (r.foregroundActivities) {
13696                foreground = 'A';
13697            } else if (r.foregroundServices) {
13698                foreground = 'S';
13699            } else {
13700                foreground = ' ';
13701            }
13702            String procState = ProcessList.makeProcStateString(r.curProcState);
13703            pw.print(prefix);
13704            pw.print(r.persistent ? persistentLabel : normalLabel);
13705            pw.print(" #");
13706            int num = (origList.size()-1)-list.get(i).second;
13707            if (num < 10) pw.print(' ');
13708            pw.print(num);
13709            pw.print(": ");
13710            pw.print(oomAdj);
13711            pw.print(' ');
13712            pw.print(schedGroup);
13713            pw.print('/');
13714            pw.print(foreground);
13715            pw.print('/');
13716            pw.print(procState);
13717            pw.print(" trm:");
13718            if (r.trimMemoryLevel < 10) pw.print(' ');
13719            pw.print(r.trimMemoryLevel);
13720            pw.print(' ');
13721            pw.print(r.toShortString());
13722            pw.print(" (");
13723            pw.print(r.adjType);
13724            pw.println(')');
13725            if (r.adjSource != null || r.adjTarget != null) {
13726                pw.print(prefix);
13727                pw.print("    ");
13728                if (r.adjTarget instanceof ComponentName) {
13729                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13730                } else if (r.adjTarget != null) {
13731                    pw.print(r.adjTarget.toString());
13732                } else {
13733                    pw.print("{null}");
13734                }
13735                pw.print("<=");
13736                if (r.adjSource instanceof ProcessRecord) {
13737                    pw.print("Proc{");
13738                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13739                    pw.println("}");
13740                } else if (r.adjSource != null) {
13741                    pw.println(r.adjSource.toString());
13742                } else {
13743                    pw.println("{null}");
13744                }
13745            }
13746            if (inclDetails) {
13747                pw.print(prefix);
13748                pw.print("    ");
13749                pw.print("oom: max="); pw.print(r.maxAdj);
13750                pw.print(" curRaw="); pw.print(r.curRawAdj);
13751                pw.print(" setRaw="); pw.print(r.setRawAdj);
13752                pw.print(" cur="); pw.print(r.curAdj);
13753                pw.print(" set="); pw.println(r.setAdj);
13754                pw.print(prefix);
13755                pw.print("    ");
13756                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13757                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13758                pw.print(" lastPss="); pw.print(r.lastPss);
13759                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13760                pw.print(prefix);
13761                pw.print("    ");
13762                pw.print("cached="); pw.print(r.cached);
13763                pw.print(" empty="); pw.print(r.empty);
13764                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13765
13766                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13767                    if (r.lastWakeTime != 0) {
13768                        long wtime;
13769                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13770                        synchronized (stats) {
13771                            wtime = stats.getProcessWakeTime(r.info.uid,
13772                                    r.pid, curRealtime);
13773                        }
13774                        long timeUsed = wtime - r.lastWakeTime;
13775                        pw.print(prefix);
13776                        pw.print("    ");
13777                        pw.print("keep awake over ");
13778                        TimeUtils.formatDuration(realtimeSince, pw);
13779                        pw.print(" used ");
13780                        TimeUtils.formatDuration(timeUsed, pw);
13781                        pw.print(" (");
13782                        pw.print((timeUsed*100)/realtimeSince);
13783                        pw.println("%)");
13784                    }
13785                    if (r.lastCpuTime != 0) {
13786                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13787                        pw.print(prefix);
13788                        pw.print("    ");
13789                        pw.print("run cpu over ");
13790                        TimeUtils.formatDuration(uptimeSince, pw);
13791                        pw.print(" used ");
13792                        TimeUtils.formatDuration(timeUsed, pw);
13793                        pw.print(" (");
13794                        pw.print((timeUsed*100)/uptimeSince);
13795                        pw.println("%)");
13796                    }
13797                }
13798            }
13799        }
13800        return true;
13801    }
13802
13803    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13804            String[] args) {
13805        ArrayList<ProcessRecord> procs;
13806        synchronized (this) {
13807            if (args != null && args.length > start
13808                    && args[start].charAt(0) != '-') {
13809                procs = new ArrayList<ProcessRecord>();
13810                int pid = -1;
13811                try {
13812                    pid = Integer.parseInt(args[start]);
13813                } catch (NumberFormatException e) {
13814                }
13815                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13816                    ProcessRecord proc = mLruProcesses.get(i);
13817                    if (proc.pid == pid) {
13818                        procs.add(proc);
13819                    } else if (allPkgs && proc.pkgList != null
13820                            && proc.pkgList.containsKey(args[start])) {
13821                        procs.add(proc);
13822                    } else if (proc.processName.equals(args[start])) {
13823                        procs.add(proc);
13824                    }
13825                }
13826                if (procs.size() <= 0) {
13827                    return null;
13828                }
13829            } else {
13830                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13831            }
13832        }
13833        return procs;
13834    }
13835
13836    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13837            PrintWriter pw, String[] args) {
13838        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13839        if (procs == null) {
13840            pw.println("No process found for: " + args[0]);
13841            return;
13842        }
13843
13844        long uptime = SystemClock.uptimeMillis();
13845        long realtime = SystemClock.elapsedRealtime();
13846        pw.println("Applications Graphics Acceleration Info:");
13847        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13848
13849        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13850            ProcessRecord r = procs.get(i);
13851            if (r.thread != null) {
13852                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13853                pw.flush();
13854                try {
13855                    TransferPipe tp = new TransferPipe();
13856                    try {
13857                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13858                        tp.go(fd);
13859                    } finally {
13860                        tp.kill();
13861                    }
13862                } catch (IOException e) {
13863                    pw.println("Failure while dumping the app: " + r);
13864                    pw.flush();
13865                } catch (RemoteException e) {
13866                    pw.println("Got a RemoteException while dumping the app " + r);
13867                    pw.flush();
13868                }
13869            }
13870        }
13871    }
13872
13873    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13874        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13875        if (procs == null) {
13876            pw.println("No process found for: " + args[0]);
13877            return;
13878        }
13879
13880        pw.println("Applications Database Info:");
13881
13882        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13883            ProcessRecord r = procs.get(i);
13884            if (r.thread != null) {
13885                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13886                pw.flush();
13887                try {
13888                    TransferPipe tp = new TransferPipe();
13889                    try {
13890                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13891                        tp.go(fd);
13892                    } finally {
13893                        tp.kill();
13894                    }
13895                } catch (IOException e) {
13896                    pw.println("Failure while dumping the app: " + r);
13897                    pw.flush();
13898                } catch (RemoteException e) {
13899                    pw.println("Got a RemoteException while dumping the app " + r);
13900                    pw.flush();
13901                }
13902            }
13903        }
13904    }
13905
13906    final static class MemItem {
13907        final boolean isProc;
13908        final String label;
13909        final String shortLabel;
13910        final long pss;
13911        final int id;
13912        final boolean hasActivities;
13913        ArrayList<MemItem> subitems;
13914
13915        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13916                boolean _hasActivities) {
13917            isProc = true;
13918            label = _label;
13919            shortLabel = _shortLabel;
13920            pss = _pss;
13921            id = _id;
13922            hasActivities = _hasActivities;
13923        }
13924
13925        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13926            isProc = false;
13927            label = _label;
13928            shortLabel = _shortLabel;
13929            pss = _pss;
13930            id = _id;
13931            hasActivities = false;
13932        }
13933    }
13934
13935    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13936            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13937        if (sort && !isCompact) {
13938            Collections.sort(items, new Comparator<MemItem>() {
13939                @Override
13940                public int compare(MemItem lhs, MemItem rhs) {
13941                    if (lhs.pss < rhs.pss) {
13942                        return 1;
13943                    } else if (lhs.pss > rhs.pss) {
13944                        return -1;
13945                    }
13946                    return 0;
13947                }
13948            });
13949        }
13950
13951        for (int i=0; i<items.size(); i++) {
13952            MemItem mi = items.get(i);
13953            if (!isCompact) {
13954                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13955            } else if (mi.isProc) {
13956                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13957                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13958                pw.println(mi.hasActivities ? ",a" : ",e");
13959            } else {
13960                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13961                pw.println(mi.pss);
13962            }
13963            if (mi.subitems != null) {
13964                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13965                        true, isCompact);
13966            }
13967        }
13968    }
13969
13970    // These are in KB.
13971    static final long[] DUMP_MEM_BUCKETS = new long[] {
13972        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13973        120*1024, 160*1024, 200*1024,
13974        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13975        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13976    };
13977
13978    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13979            boolean stackLike) {
13980        int start = label.lastIndexOf('.');
13981        if (start >= 0) start++;
13982        else start = 0;
13983        int end = label.length();
13984        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13985            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13986                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13987                out.append(bucket);
13988                out.append(stackLike ? "MB." : "MB ");
13989                out.append(label, start, end);
13990                return;
13991            }
13992        }
13993        out.append(memKB/1024);
13994        out.append(stackLike ? "MB." : "MB ");
13995        out.append(label, start, end);
13996    }
13997
13998    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13999            ProcessList.NATIVE_ADJ,
14000            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14001            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14002            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14003            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14004            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14005            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14006    };
14007    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14008            "Native",
14009            "System", "Persistent", "Persistent Service", "Foreground",
14010            "Visible", "Perceptible",
14011            "Heavy Weight", "Backup",
14012            "A Services", "Home",
14013            "Previous", "B Services", "Cached"
14014    };
14015    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14016            "native",
14017            "sys", "pers", "persvc", "fore",
14018            "vis", "percept",
14019            "heavy", "backup",
14020            "servicea", "home",
14021            "prev", "serviceb", "cached"
14022    };
14023
14024    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14025            long realtime, boolean isCheckinRequest, boolean isCompact) {
14026        if (isCheckinRequest || isCompact) {
14027            // short checkin version
14028            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14029        } else {
14030            pw.println("Applications Memory Usage (kB):");
14031            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14032        }
14033    }
14034
14035    private static final int KSM_SHARED = 0;
14036    private static final int KSM_SHARING = 1;
14037    private static final int KSM_UNSHARED = 2;
14038    private static final int KSM_VOLATILE = 3;
14039
14040    private final long[] getKsmInfo() {
14041        long[] longOut = new long[4];
14042        final int[] SINGLE_LONG_FORMAT = new int[] {
14043            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14044        };
14045        long[] longTmp = new long[1];
14046        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14047                SINGLE_LONG_FORMAT, null, longTmp, null);
14048        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14049        longTmp[0] = 0;
14050        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14051                SINGLE_LONG_FORMAT, null, longTmp, null);
14052        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14053        longTmp[0] = 0;
14054        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14055                SINGLE_LONG_FORMAT, null, longTmp, null);
14056        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14057        longTmp[0] = 0;
14058        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14059                SINGLE_LONG_FORMAT, null, longTmp, null);
14060        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14061        return longOut;
14062    }
14063
14064    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14065            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14066        boolean dumpDetails = false;
14067        boolean dumpFullDetails = false;
14068        boolean dumpDalvik = false;
14069        boolean oomOnly = false;
14070        boolean isCompact = false;
14071        boolean localOnly = false;
14072        boolean packages = false;
14073
14074        int opti = 0;
14075        while (opti < args.length) {
14076            String opt = args[opti];
14077            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14078                break;
14079            }
14080            opti++;
14081            if ("-a".equals(opt)) {
14082                dumpDetails = true;
14083                dumpFullDetails = true;
14084                dumpDalvik = true;
14085            } else if ("-d".equals(opt)) {
14086                dumpDalvik = true;
14087            } else if ("-c".equals(opt)) {
14088                isCompact = true;
14089            } else if ("--oom".equals(opt)) {
14090                oomOnly = true;
14091            } else if ("--local".equals(opt)) {
14092                localOnly = true;
14093            } else if ("--package".equals(opt)) {
14094                packages = true;
14095            } else if ("-h".equals(opt)) {
14096                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14097                pw.println("  -a: include all available information for each process.");
14098                pw.println("  -d: include dalvik details when dumping process details.");
14099                pw.println("  -c: dump in a compact machine-parseable representation.");
14100                pw.println("  --oom: only show processes organized by oom adj.");
14101                pw.println("  --local: only collect details locally, don't call process.");
14102                pw.println("  --package: interpret process arg as package, dumping all");
14103                pw.println("             processes that have loaded that package.");
14104                pw.println("If [process] is specified it can be the name or ");
14105                pw.println("pid of a specific process to dump.");
14106                return;
14107            } else {
14108                pw.println("Unknown argument: " + opt + "; use -h for help");
14109            }
14110        }
14111
14112        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14113        long uptime = SystemClock.uptimeMillis();
14114        long realtime = SystemClock.elapsedRealtime();
14115        final long[] tmpLong = new long[1];
14116
14117        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14118        if (procs == null) {
14119            // No Java processes.  Maybe they want to print a native process.
14120            if (args != null && args.length > opti
14121                    && args[opti].charAt(0) != '-') {
14122                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14123                        = new ArrayList<ProcessCpuTracker.Stats>();
14124                updateCpuStatsNow();
14125                int findPid = -1;
14126                try {
14127                    findPid = Integer.parseInt(args[opti]);
14128                } catch (NumberFormatException e) {
14129                }
14130                synchronized (mProcessCpuTracker) {
14131                    final int N = mProcessCpuTracker.countStats();
14132                    for (int i=0; i<N; i++) {
14133                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14134                        if (st.pid == findPid || (st.baseName != null
14135                                && st.baseName.equals(args[opti]))) {
14136                            nativeProcs.add(st);
14137                        }
14138                    }
14139                }
14140                if (nativeProcs.size() > 0) {
14141                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14142                            isCompact);
14143                    Debug.MemoryInfo mi = null;
14144                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14145                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14146                        final int pid = r.pid;
14147                        if (!isCheckinRequest && dumpDetails) {
14148                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14149                        }
14150                        if (mi == null) {
14151                            mi = new Debug.MemoryInfo();
14152                        }
14153                        if (dumpDetails || (!brief && !oomOnly)) {
14154                            Debug.getMemoryInfo(pid, mi);
14155                        } else {
14156                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14157                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14158                        }
14159                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14160                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14161                        if (isCheckinRequest) {
14162                            pw.println();
14163                        }
14164                    }
14165                    return;
14166                }
14167            }
14168            pw.println("No process found for: " + args[opti]);
14169            return;
14170        }
14171
14172        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14173            dumpDetails = true;
14174        }
14175
14176        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14177
14178        String[] innerArgs = new String[args.length-opti];
14179        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14180
14181        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14182        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14183        long nativePss = 0;
14184        long dalvikPss = 0;
14185        long otherPss = 0;
14186        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14187
14188        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14189        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14190                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14191
14192        long totalPss = 0;
14193        long cachedPss = 0;
14194
14195        Debug.MemoryInfo mi = null;
14196        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14197            final ProcessRecord r = procs.get(i);
14198            final IApplicationThread thread;
14199            final int pid;
14200            final int oomAdj;
14201            final boolean hasActivities;
14202            synchronized (this) {
14203                thread = r.thread;
14204                pid = r.pid;
14205                oomAdj = r.getSetAdjWithServices();
14206                hasActivities = r.activities.size() > 0;
14207            }
14208            if (thread != null) {
14209                if (!isCheckinRequest && dumpDetails) {
14210                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14211                }
14212                if (mi == null) {
14213                    mi = new Debug.MemoryInfo();
14214                }
14215                if (dumpDetails || (!brief && !oomOnly)) {
14216                    Debug.getMemoryInfo(pid, mi);
14217                } else {
14218                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14219                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14220                }
14221                if (dumpDetails) {
14222                    if (localOnly) {
14223                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14224                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14225                        if (isCheckinRequest) {
14226                            pw.println();
14227                        }
14228                    } else {
14229                        try {
14230                            pw.flush();
14231                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14232                                    dumpDalvik, innerArgs);
14233                        } catch (RemoteException e) {
14234                            if (!isCheckinRequest) {
14235                                pw.println("Got RemoteException!");
14236                                pw.flush();
14237                            }
14238                        }
14239                    }
14240                }
14241
14242                final long myTotalPss = mi.getTotalPss();
14243                final long myTotalUss = mi.getTotalUss();
14244
14245                synchronized (this) {
14246                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14247                        // Record this for posterity if the process has been stable.
14248                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14249                    }
14250                }
14251
14252                if (!isCheckinRequest && mi != null) {
14253                    totalPss += myTotalPss;
14254                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14255                            (hasActivities ? " / activities)" : ")"),
14256                            r.processName, myTotalPss, pid, hasActivities);
14257                    procMems.add(pssItem);
14258                    procMemsMap.put(pid, pssItem);
14259
14260                    nativePss += mi.nativePss;
14261                    dalvikPss += mi.dalvikPss;
14262                    otherPss += mi.otherPss;
14263                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14264                        long mem = mi.getOtherPss(j);
14265                        miscPss[j] += mem;
14266                        otherPss -= mem;
14267                    }
14268
14269                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14270                        cachedPss += myTotalPss;
14271                    }
14272
14273                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14274                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14275                                || oomIndex == (oomPss.length-1)) {
14276                            oomPss[oomIndex] += myTotalPss;
14277                            if (oomProcs[oomIndex] == null) {
14278                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14279                            }
14280                            oomProcs[oomIndex].add(pssItem);
14281                            break;
14282                        }
14283                    }
14284                }
14285            }
14286        }
14287
14288        long nativeProcTotalPss = 0;
14289
14290        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14291            // If we are showing aggregations, also look for native processes to
14292            // include so that our aggregations are more accurate.
14293            updateCpuStatsNow();
14294            mi = null;
14295            synchronized (mProcessCpuTracker) {
14296                final int N = mProcessCpuTracker.countStats();
14297                for (int i=0; i<N; i++) {
14298                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14299                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14300                        if (mi == null) {
14301                            mi = new Debug.MemoryInfo();
14302                        }
14303                        if (!brief && !oomOnly) {
14304                            Debug.getMemoryInfo(st.pid, mi);
14305                        } else {
14306                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14307                            mi.nativePrivateDirty = (int)tmpLong[0];
14308                        }
14309
14310                        final long myTotalPss = mi.getTotalPss();
14311                        totalPss += myTotalPss;
14312                        nativeProcTotalPss += myTotalPss;
14313
14314                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14315                                st.name, myTotalPss, st.pid, false);
14316                        procMems.add(pssItem);
14317
14318                        nativePss += mi.nativePss;
14319                        dalvikPss += mi.dalvikPss;
14320                        otherPss += mi.otherPss;
14321                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14322                            long mem = mi.getOtherPss(j);
14323                            miscPss[j] += mem;
14324                            otherPss -= mem;
14325                        }
14326                        oomPss[0] += myTotalPss;
14327                        if (oomProcs[0] == null) {
14328                            oomProcs[0] = new ArrayList<MemItem>();
14329                        }
14330                        oomProcs[0].add(pssItem);
14331                    }
14332                }
14333            }
14334
14335            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14336
14337            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14338            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14339            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14340            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14341                String label = Debug.MemoryInfo.getOtherLabel(j);
14342                catMems.add(new MemItem(label, label, miscPss[j], j));
14343            }
14344
14345            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14346            for (int j=0; j<oomPss.length; j++) {
14347                if (oomPss[j] != 0) {
14348                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14349                            : DUMP_MEM_OOM_LABEL[j];
14350                    MemItem item = new MemItem(label, label, oomPss[j],
14351                            DUMP_MEM_OOM_ADJ[j]);
14352                    item.subitems = oomProcs[j];
14353                    oomMems.add(item);
14354                }
14355            }
14356
14357            if (!brief && !oomOnly && !isCompact) {
14358                pw.println();
14359                pw.println("Total PSS by process:");
14360                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14361                pw.println();
14362            }
14363            if (!isCompact) {
14364                pw.println("Total PSS by OOM adjustment:");
14365            }
14366            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14367            if (!brief && !oomOnly) {
14368                PrintWriter out = categoryPw != null ? categoryPw : pw;
14369                if (!isCompact) {
14370                    out.println();
14371                    out.println("Total PSS by category:");
14372                }
14373                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14374            }
14375            if (!isCompact) {
14376                pw.println();
14377            }
14378            MemInfoReader memInfo = new MemInfoReader();
14379            memInfo.readMemInfo();
14380            if (nativeProcTotalPss > 0) {
14381                synchronized (this) {
14382                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14383                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14384                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14385                }
14386            }
14387            if (!brief) {
14388                if (!isCompact) {
14389                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14390                    pw.print(" kB (status ");
14391                    switch (mLastMemoryLevel) {
14392                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14393                            pw.println("normal)");
14394                            break;
14395                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14396                            pw.println("moderate)");
14397                            break;
14398                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14399                            pw.println("low)");
14400                            break;
14401                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14402                            pw.println("critical)");
14403                            break;
14404                        default:
14405                            pw.print(mLastMemoryLevel);
14406                            pw.println(")");
14407                            break;
14408                    }
14409                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14410                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14411                            pw.print(cachedPss); pw.print(" cached pss + ");
14412                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14413                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14414                } else {
14415                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14416                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14417                            + memInfo.getFreeSizeKb()); pw.print(",");
14418                    pw.println(totalPss - cachedPss);
14419                }
14420            }
14421            if (!isCompact) {
14422                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14423                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14424                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14425                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14426                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14427                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14428                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14429            }
14430            if (!brief) {
14431                if (memInfo.getZramTotalSizeKb() != 0) {
14432                    if (!isCompact) {
14433                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14434                                pw.print(" kB physical used for ");
14435                                pw.print(memInfo.getSwapTotalSizeKb()
14436                                        - memInfo.getSwapFreeSizeKb());
14437                                pw.print(" kB in swap (");
14438                                pw.print(memInfo.getSwapTotalSizeKb());
14439                                pw.println(" kB total swap)");
14440                    } else {
14441                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14442                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14443                                pw.println(memInfo.getSwapFreeSizeKb());
14444                    }
14445                }
14446                final long[] ksm = getKsmInfo();
14447                if (!isCompact) {
14448                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14449                            || ksm[KSM_VOLATILE] != 0) {
14450                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14451                                pw.print(" kB saved from shared ");
14452                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14453                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14454                                pw.print(" kB unshared; ");
14455                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14456                    }
14457                    pw.print("   Tuning: ");
14458                    pw.print(ActivityManager.staticGetMemoryClass());
14459                    pw.print(" (large ");
14460                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14461                    pw.print("), oom ");
14462                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14463                    pw.print(" kB");
14464                    pw.print(", restore limit ");
14465                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14466                    pw.print(" kB");
14467                    if (ActivityManager.isLowRamDeviceStatic()) {
14468                        pw.print(" (low-ram)");
14469                    }
14470                    if (ActivityManager.isHighEndGfx()) {
14471                        pw.print(" (high-end-gfx)");
14472                    }
14473                    pw.println();
14474                } else {
14475                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14476                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14477                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14478                    pw.print("tuning,");
14479                    pw.print(ActivityManager.staticGetMemoryClass());
14480                    pw.print(',');
14481                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14482                    pw.print(',');
14483                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14484                    if (ActivityManager.isLowRamDeviceStatic()) {
14485                        pw.print(",low-ram");
14486                    }
14487                    if (ActivityManager.isHighEndGfx()) {
14488                        pw.print(",high-end-gfx");
14489                    }
14490                    pw.println();
14491                }
14492            }
14493        }
14494    }
14495
14496    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14497            long memtrack, String name) {
14498        sb.append("  ");
14499        sb.append(ProcessList.makeOomAdjString(oomAdj));
14500        sb.append(' ');
14501        sb.append(ProcessList.makeProcStateString(procState));
14502        sb.append(' ');
14503        ProcessList.appendRamKb(sb, pss);
14504        sb.append(" kB: ");
14505        sb.append(name);
14506        if (memtrack > 0) {
14507            sb.append(" (");
14508            sb.append(memtrack);
14509            sb.append(" kB memtrack)");
14510        }
14511    }
14512
14513    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14514        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14515        sb.append(" (pid ");
14516        sb.append(mi.pid);
14517        sb.append(") ");
14518        sb.append(mi.adjType);
14519        sb.append('\n');
14520        if (mi.adjReason != null) {
14521            sb.append("                      ");
14522            sb.append(mi.adjReason);
14523            sb.append('\n');
14524        }
14525    }
14526
14527    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14528        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14529        for (int i=0, N=memInfos.size(); i<N; i++) {
14530            ProcessMemInfo mi = memInfos.get(i);
14531            infoMap.put(mi.pid, mi);
14532        }
14533        updateCpuStatsNow();
14534        long[] memtrackTmp = new long[1];
14535        synchronized (mProcessCpuTracker) {
14536            final int N = mProcessCpuTracker.countStats();
14537            for (int i=0; i<N; i++) {
14538                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14539                if (st.vsize > 0) {
14540                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14541                    if (pss > 0) {
14542                        if (infoMap.indexOfKey(st.pid) < 0) {
14543                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14544                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14545                            mi.pss = pss;
14546                            mi.memtrack = memtrackTmp[0];
14547                            memInfos.add(mi);
14548                        }
14549                    }
14550                }
14551            }
14552        }
14553
14554        long totalPss = 0;
14555        long totalMemtrack = 0;
14556        for (int i=0, N=memInfos.size(); i<N; i++) {
14557            ProcessMemInfo mi = memInfos.get(i);
14558            if (mi.pss == 0) {
14559                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14560                mi.memtrack = memtrackTmp[0];
14561            }
14562            totalPss += mi.pss;
14563            totalMemtrack += mi.memtrack;
14564        }
14565        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14566            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14567                if (lhs.oomAdj != rhs.oomAdj) {
14568                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14569                }
14570                if (lhs.pss != rhs.pss) {
14571                    return lhs.pss < rhs.pss ? 1 : -1;
14572                }
14573                return 0;
14574            }
14575        });
14576
14577        StringBuilder tag = new StringBuilder(128);
14578        StringBuilder stack = new StringBuilder(128);
14579        tag.append("Low on memory -- ");
14580        appendMemBucket(tag, totalPss, "total", false);
14581        appendMemBucket(stack, totalPss, "total", true);
14582
14583        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14584        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14585        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14586
14587        boolean firstLine = true;
14588        int lastOomAdj = Integer.MIN_VALUE;
14589        long extraNativeRam = 0;
14590        long extraNativeMemtrack = 0;
14591        long cachedPss = 0;
14592        for (int i=0, N=memInfos.size(); i<N; i++) {
14593            ProcessMemInfo mi = memInfos.get(i);
14594
14595            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14596                cachedPss += mi.pss;
14597            }
14598
14599            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14600                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14601                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14602                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14603                if (lastOomAdj != mi.oomAdj) {
14604                    lastOomAdj = mi.oomAdj;
14605                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14606                        tag.append(" / ");
14607                    }
14608                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14609                        if (firstLine) {
14610                            stack.append(":");
14611                            firstLine = false;
14612                        }
14613                        stack.append("\n\t at ");
14614                    } else {
14615                        stack.append("$");
14616                    }
14617                } else {
14618                    tag.append(" ");
14619                    stack.append("$");
14620                }
14621                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14622                    appendMemBucket(tag, mi.pss, mi.name, false);
14623                }
14624                appendMemBucket(stack, mi.pss, mi.name, true);
14625                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14626                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14627                    stack.append("(");
14628                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14629                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14630                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14631                            stack.append(":");
14632                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14633                        }
14634                    }
14635                    stack.append(")");
14636                }
14637            }
14638
14639            appendMemInfo(fullNativeBuilder, mi);
14640            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14641                // The short form only has native processes that are >= 512K.
14642                if (mi.pss >= 512) {
14643                    appendMemInfo(shortNativeBuilder, mi);
14644                } else {
14645                    extraNativeRam += mi.pss;
14646                    extraNativeMemtrack += mi.memtrack;
14647                }
14648            } else {
14649                // Short form has all other details, but if we have collected RAM
14650                // from smaller native processes let's dump a summary of that.
14651                if (extraNativeRam > 0) {
14652                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14653                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14654                    shortNativeBuilder.append('\n');
14655                    extraNativeRam = 0;
14656                }
14657                appendMemInfo(fullJavaBuilder, mi);
14658            }
14659        }
14660
14661        fullJavaBuilder.append("           ");
14662        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14663        fullJavaBuilder.append(" kB: TOTAL");
14664        if (totalMemtrack > 0) {
14665            fullJavaBuilder.append(" (");
14666            fullJavaBuilder.append(totalMemtrack);
14667            fullJavaBuilder.append(" kB memtrack)");
14668        } else {
14669        }
14670        fullJavaBuilder.append("\n");
14671
14672        MemInfoReader memInfo = new MemInfoReader();
14673        memInfo.readMemInfo();
14674        final long[] infos = memInfo.getRawInfo();
14675
14676        StringBuilder memInfoBuilder = new StringBuilder(1024);
14677        Debug.getMemInfo(infos);
14678        memInfoBuilder.append("  MemInfo: ");
14679        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14680        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14681        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14682        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14683        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14684        memInfoBuilder.append("           ");
14685        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14686        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14687        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14688        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14689        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14690            memInfoBuilder.append("  ZRAM: ");
14691            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14692            memInfoBuilder.append(" kB RAM, ");
14693            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14694            memInfoBuilder.append(" kB swap total, ");
14695            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14696            memInfoBuilder.append(" kB swap free\n");
14697        }
14698        final long[] ksm = getKsmInfo();
14699        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14700                || ksm[KSM_VOLATILE] != 0) {
14701            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14702            memInfoBuilder.append(" kB saved from shared ");
14703            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14704            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14705            memInfoBuilder.append(" kB unshared; ");
14706            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14707        }
14708        memInfoBuilder.append("  Free RAM: ");
14709        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14710                + memInfo.getFreeSizeKb());
14711        memInfoBuilder.append(" kB\n");
14712        memInfoBuilder.append("  Used RAM: ");
14713        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14714        memInfoBuilder.append(" kB\n");
14715        memInfoBuilder.append("  Lost RAM: ");
14716        memInfoBuilder.append(memInfo.getTotalSizeKb()
14717                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14718                - memInfo.getKernelUsedSizeKb());
14719        memInfoBuilder.append(" kB\n");
14720        Slog.i(TAG, "Low on memory:");
14721        Slog.i(TAG, shortNativeBuilder.toString());
14722        Slog.i(TAG, fullJavaBuilder.toString());
14723        Slog.i(TAG, memInfoBuilder.toString());
14724
14725        StringBuilder dropBuilder = new StringBuilder(1024);
14726        /*
14727        StringWriter oomSw = new StringWriter();
14728        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14729        StringWriter catSw = new StringWriter();
14730        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14731        String[] emptyArgs = new String[] { };
14732        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14733        oomPw.flush();
14734        String oomString = oomSw.toString();
14735        */
14736        dropBuilder.append("Low on memory:");
14737        dropBuilder.append(stack);
14738        dropBuilder.append('\n');
14739        dropBuilder.append(fullNativeBuilder);
14740        dropBuilder.append(fullJavaBuilder);
14741        dropBuilder.append('\n');
14742        dropBuilder.append(memInfoBuilder);
14743        dropBuilder.append('\n');
14744        /*
14745        dropBuilder.append(oomString);
14746        dropBuilder.append('\n');
14747        */
14748        StringWriter catSw = new StringWriter();
14749        synchronized (ActivityManagerService.this) {
14750            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14751            String[] emptyArgs = new String[] { };
14752            catPw.println();
14753            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14754            catPw.println();
14755            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14756                    false, false, null);
14757            catPw.println();
14758            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14759            catPw.flush();
14760        }
14761        dropBuilder.append(catSw.toString());
14762        addErrorToDropBox("lowmem", null, "system_server", null,
14763                null, tag.toString(), dropBuilder.toString(), null, null);
14764        //Slog.i(TAG, "Sent to dropbox:");
14765        //Slog.i(TAG, dropBuilder.toString());
14766        synchronized (ActivityManagerService.this) {
14767            long now = SystemClock.uptimeMillis();
14768            if (mLastMemUsageReportTime < now) {
14769                mLastMemUsageReportTime = now;
14770            }
14771        }
14772    }
14773
14774    /**
14775     * Searches array of arguments for the specified string
14776     * @param args array of argument strings
14777     * @param value value to search for
14778     * @return true if the value is contained in the array
14779     */
14780    private static boolean scanArgs(String[] args, String value) {
14781        if (args != null) {
14782            for (String arg : args) {
14783                if (value.equals(arg)) {
14784                    return true;
14785                }
14786            }
14787        }
14788        return false;
14789    }
14790
14791    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14792            ContentProviderRecord cpr, boolean always) {
14793        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14794
14795        if (!inLaunching || always) {
14796            synchronized (cpr) {
14797                cpr.launchingApp = null;
14798                cpr.notifyAll();
14799            }
14800            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14801            String names[] = cpr.info.authority.split(";");
14802            for (int j = 0; j < names.length; j++) {
14803                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14804            }
14805        }
14806
14807        for (int i=0; i<cpr.connections.size(); i++) {
14808            ContentProviderConnection conn = cpr.connections.get(i);
14809            if (conn.waiting) {
14810                // If this connection is waiting for the provider, then we don't
14811                // need to mess with its process unless we are always removing
14812                // or for some reason the provider is not currently launching.
14813                if (inLaunching && !always) {
14814                    continue;
14815                }
14816            }
14817            ProcessRecord capp = conn.client;
14818            conn.dead = true;
14819            if (conn.stableCount > 0) {
14820                if (!capp.persistent && capp.thread != null
14821                        && capp.pid != 0
14822                        && capp.pid != MY_PID) {
14823                    capp.kill("depends on provider "
14824                            + cpr.name.flattenToShortString()
14825                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14826                }
14827            } else if (capp.thread != null && conn.provider.provider != null) {
14828                try {
14829                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14830                } catch (RemoteException e) {
14831                }
14832                // In the protocol here, we don't expect the client to correctly
14833                // clean up this connection, we'll just remove it.
14834                cpr.connections.remove(i);
14835                if (conn.client.conProviders.remove(conn)) {
14836                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14837                }
14838            }
14839        }
14840
14841        if (inLaunching && always) {
14842            mLaunchingProviders.remove(cpr);
14843        }
14844        return inLaunching;
14845    }
14846
14847    /**
14848     * Main code for cleaning up a process when it has gone away.  This is
14849     * called both as a result of the process dying, or directly when stopping
14850     * a process when running in single process mode.
14851     *
14852     * @return Returns true if the given process has been restarted, so the
14853     * app that was passed in must remain on the process lists.
14854     */
14855    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14856            boolean restarting, boolean allowRestart, int index) {
14857        if (index >= 0) {
14858            removeLruProcessLocked(app);
14859            ProcessList.remove(app.pid);
14860        }
14861
14862        mProcessesToGc.remove(app);
14863        mPendingPssProcesses.remove(app);
14864
14865        // Dismiss any open dialogs.
14866        if (app.crashDialog != null && !app.forceCrashReport) {
14867            app.crashDialog.dismiss();
14868            app.crashDialog = null;
14869        }
14870        if (app.anrDialog != null) {
14871            app.anrDialog.dismiss();
14872            app.anrDialog = null;
14873        }
14874        if (app.waitDialog != null) {
14875            app.waitDialog.dismiss();
14876            app.waitDialog = null;
14877        }
14878
14879        app.crashing = false;
14880        app.notResponding = false;
14881
14882        app.resetPackageList(mProcessStats);
14883        app.unlinkDeathRecipient();
14884        app.makeInactive(mProcessStats);
14885        app.waitingToKill = null;
14886        app.forcingToForeground = null;
14887        updateProcessForegroundLocked(app, false, false);
14888        app.foregroundActivities = false;
14889        app.hasShownUi = false;
14890        app.treatLikeActivity = false;
14891        app.hasAboveClient = false;
14892        app.hasClientActivities = false;
14893
14894        mServices.killServicesLocked(app, allowRestart);
14895
14896        boolean restart = false;
14897
14898        // Remove published content providers.
14899        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14900            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14901            final boolean always = app.bad || !allowRestart;
14902            if (removeDyingProviderLocked(app, cpr, always) || always) {
14903                // We left the provider in the launching list, need to
14904                // restart it.
14905                restart = true;
14906            }
14907
14908            cpr.provider = null;
14909            cpr.proc = null;
14910        }
14911        app.pubProviders.clear();
14912
14913        // Take care of any launching providers waiting for this process.
14914        if (checkAppInLaunchingProvidersLocked(app, false)) {
14915            restart = true;
14916        }
14917
14918        // Unregister from connected content providers.
14919        if (!app.conProviders.isEmpty()) {
14920            for (int i=0; i<app.conProviders.size(); i++) {
14921                ContentProviderConnection conn = app.conProviders.get(i);
14922                conn.provider.connections.remove(conn);
14923                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14924                        conn.provider.name);
14925            }
14926            app.conProviders.clear();
14927        }
14928
14929        // At this point there may be remaining entries in mLaunchingProviders
14930        // where we were the only one waiting, so they are no longer of use.
14931        // Look for these and clean up if found.
14932        // XXX Commented out for now.  Trying to figure out a way to reproduce
14933        // the actual situation to identify what is actually going on.
14934        if (false) {
14935            for (int i=0; i<mLaunchingProviders.size(); i++) {
14936                ContentProviderRecord cpr = (ContentProviderRecord)
14937                        mLaunchingProviders.get(i);
14938                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14939                    synchronized (cpr) {
14940                        cpr.launchingApp = null;
14941                        cpr.notifyAll();
14942                    }
14943                }
14944            }
14945        }
14946
14947        skipCurrentReceiverLocked(app);
14948
14949        // Unregister any receivers.
14950        for (int i=app.receivers.size()-1; i>=0; i--) {
14951            removeReceiverLocked(app.receivers.valueAt(i));
14952        }
14953        app.receivers.clear();
14954
14955        // If the app is undergoing backup, tell the backup manager about it
14956        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14957            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14958                    + mBackupTarget.appInfo + " died during backup");
14959            try {
14960                IBackupManager bm = IBackupManager.Stub.asInterface(
14961                        ServiceManager.getService(Context.BACKUP_SERVICE));
14962                bm.agentDisconnected(app.info.packageName);
14963            } catch (RemoteException e) {
14964                // can't happen; backup manager is local
14965            }
14966        }
14967
14968        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14969            ProcessChangeItem item = mPendingProcessChanges.get(i);
14970            if (item.pid == app.pid) {
14971                mPendingProcessChanges.remove(i);
14972                mAvailProcessChanges.add(item);
14973            }
14974        }
14975        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14976
14977        // If the caller is restarting this app, then leave it in its
14978        // current lists and let the caller take care of it.
14979        if (restarting) {
14980            return false;
14981        }
14982
14983        if (!app.persistent || app.isolated) {
14984            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14985                    "Removing non-persistent process during cleanup: " + app);
14986            mProcessNames.remove(app.processName, app.uid);
14987            mIsolatedProcesses.remove(app.uid);
14988            if (mHeavyWeightProcess == app) {
14989                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14990                        mHeavyWeightProcess.userId, 0));
14991                mHeavyWeightProcess = null;
14992            }
14993        } else if (!app.removed) {
14994            // This app is persistent, so we need to keep its record around.
14995            // If it is not already on the pending app list, add it there
14996            // and start a new process for it.
14997            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14998                mPersistentStartingProcesses.add(app);
14999                restart = true;
15000            }
15001        }
15002        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15003                "Clean-up removing on hold: " + app);
15004        mProcessesOnHold.remove(app);
15005
15006        if (app == mHomeProcess) {
15007            mHomeProcess = null;
15008        }
15009        if (app == mPreviousProcess) {
15010            mPreviousProcess = null;
15011        }
15012
15013        if (restart && !app.isolated) {
15014            // We have components that still need to be running in the
15015            // process, so re-launch it.
15016            if (index < 0) {
15017                ProcessList.remove(app.pid);
15018            }
15019            mProcessNames.put(app.processName, app.uid, app);
15020            startProcessLocked(app, "restart", app.processName);
15021            return true;
15022        } else if (app.pid > 0 && app.pid != MY_PID) {
15023            // Goodbye!
15024            boolean removed;
15025            synchronized (mPidsSelfLocked) {
15026                mPidsSelfLocked.remove(app.pid);
15027                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15028            }
15029            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15030            if (app.isolated) {
15031                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15032            }
15033            app.setPid(0);
15034        }
15035        return false;
15036    }
15037
15038    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15039        // Look through the content providers we are waiting to have launched,
15040        // and if any run in this process then either schedule a restart of
15041        // the process or kill the client waiting for it if this process has
15042        // gone bad.
15043        int NL = mLaunchingProviders.size();
15044        boolean restart = false;
15045        for (int i=0; i<NL; i++) {
15046            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15047            if (cpr.launchingApp == app) {
15048                if (!alwaysBad && !app.bad) {
15049                    restart = true;
15050                } else {
15051                    removeDyingProviderLocked(app, cpr, true);
15052                    // cpr should have been removed from mLaunchingProviders
15053                    NL = mLaunchingProviders.size();
15054                    i--;
15055                }
15056            }
15057        }
15058        return restart;
15059    }
15060
15061    // =========================================================
15062    // SERVICES
15063    // =========================================================
15064
15065    @Override
15066    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15067            int flags) {
15068        enforceNotIsolatedCaller("getServices");
15069        synchronized (this) {
15070            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15071        }
15072    }
15073
15074    @Override
15075    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15076        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15077        synchronized (this) {
15078            return mServices.getRunningServiceControlPanelLocked(name);
15079        }
15080    }
15081
15082    @Override
15083    public ComponentName startService(IApplicationThread caller, Intent service,
15084            String resolvedType, int userId) {
15085        enforceNotIsolatedCaller("startService");
15086        // Refuse possible leaked file descriptors
15087        if (service != null && service.hasFileDescriptors() == true) {
15088            throw new IllegalArgumentException("File descriptors passed in Intent");
15089        }
15090
15091        if (DEBUG_SERVICE)
15092            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15093        synchronized(this) {
15094            final int callingPid = Binder.getCallingPid();
15095            final int callingUid = Binder.getCallingUid();
15096            final long origId = Binder.clearCallingIdentity();
15097            ComponentName res = mServices.startServiceLocked(caller, service,
15098                    resolvedType, callingPid, callingUid, userId);
15099            Binder.restoreCallingIdentity(origId);
15100            return res;
15101        }
15102    }
15103
15104    ComponentName startServiceInPackage(int uid,
15105            Intent service, String resolvedType, int userId) {
15106        synchronized(this) {
15107            if (DEBUG_SERVICE)
15108                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15109            final long origId = Binder.clearCallingIdentity();
15110            ComponentName res = mServices.startServiceLocked(null, service,
15111                    resolvedType, -1, uid, userId);
15112            Binder.restoreCallingIdentity(origId);
15113            return res;
15114        }
15115    }
15116
15117    @Override
15118    public int stopService(IApplicationThread caller, Intent service,
15119            String resolvedType, int userId) {
15120        enforceNotIsolatedCaller("stopService");
15121        // Refuse possible leaked file descriptors
15122        if (service != null && service.hasFileDescriptors() == true) {
15123            throw new IllegalArgumentException("File descriptors passed in Intent");
15124        }
15125
15126        synchronized(this) {
15127            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15128        }
15129    }
15130
15131    @Override
15132    public IBinder peekService(Intent service, String resolvedType) {
15133        enforceNotIsolatedCaller("peekService");
15134        // Refuse possible leaked file descriptors
15135        if (service != null && service.hasFileDescriptors() == true) {
15136            throw new IllegalArgumentException("File descriptors passed in Intent");
15137        }
15138        synchronized(this) {
15139            return mServices.peekServiceLocked(service, resolvedType);
15140        }
15141    }
15142
15143    @Override
15144    public boolean stopServiceToken(ComponentName className, IBinder token,
15145            int startId) {
15146        synchronized(this) {
15147            return mServices.stopServiceTokenLocked(className, token, startId);
15148        }
15149    }
15150
15151    @Override
15152    public void setServiceForeground(ComponentName className, IBinder token,
15153            int id, Notification notification, boolean removeNotification) {
15154        synchronized(this) {
15155            mServices.setServiceForegroundLocked(className, token, id, notification,
15156                    removeNotification);
15157        }
15158    }
15159
15160    @Override
15161    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15162            boolean requireFull, String name, String callerPackage) {
15163        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15164                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15165    }
15166
15167    int unsafeConvertIncomingUser(int userId) {
15168        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15169                ? mCurrentUserId : userId;
15170    }
15171
15172    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15173            int allowMode, String name, String callerPackage) {
15174        final int callingUserId = UserHandle.getUserId(callingUid);
15175        if (callingUserId == userId) {
15176            return userId;
15177        }
15178
15179        // Note that we may be accessing mCurrentUserId outside of a lock...
15180        // shouldn't be a big deal, if this is being called outside
15181        // of a locked context there is intrinsically a race with
15182        // the value the caller will receive and someone else changing it.
15183        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15184        // we will switch to the calling user if access to the current user fails.
15185        int targetUserId = unsafeConvertIncomingUser(userId);
15186
15187        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15188            final boolean allow;
15189            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15190                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15191                // If the caller has this permission, they always pass go.  And collect $200.
15192                allow = true;
15193            } else if (allowMode == ALLOW_FULL_ONLY) {
15194                // We require full access, sucks to be you.
15195                allow = false;
15196            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15197                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15198                // If the caller does not have either permission, they are always doomed.
15199                allow = false;
15200            } else if (allowMode == ALLOW_NON_FULL) {
15201                // We are blanket allowing non-full access, you lucky caller!
15202                allow = true;
15203            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15204                // We may or may not allow this depending on whether the two users are
15205                // in the same profile.
15206                synchronized (mUserProfileGroupIdsSelfLocked) {
15207                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15208                            UserInfo.NO_PROFILE_GROUP_ID);
15209                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15210                            UserInfo.NO_PROFILE_GROUP_ID);
15211                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15212                            && callingProfile == targetProfile;
15213                }
15214            } else {
15215                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15216            }
15217            if (!allow) {
15218                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15219                    // In this case, they would like to just execute as their
15220                    // owner user instead of failing.
15221                    targetUserId = callingUserId;
15222                } else {
15223                    StringBuilder builder = new StringBuilder(128);
15224                    builder.append("Permission Denial: ");
15225                    builder.append(name);
15226                    if (callerPackage != null) {
15227                        builder.append(" from ");
15228                        builder.append(callerPackage);
15229                    }
15230                    builder.append(" asks to run as user ");
15231                    builder.append(userId);
15232                    builder.append(" but is calling from user ");
15233                    builder.append(UserHandle.getUserId(callingUid));
15234                    builder.append("; this requires ");
15235                    builder.append(INTERACT_ACROSS_USERS_FULL);
15236                    if (allowMode != ALLOW_FULL_ONLY) {
15237                        builder.append(" or ");
15238                        builder.append(INTERACT_ACROSS_USERS);
15239                    }
15240                    String msg = builder.toString();
15241                    Slog.w(TAG, msg);
15242                    throw new SecurityException(msg);
15243                }
15244            }
15245        }
15246        if (!allowAll && targetUserId < 0) {
15247            throw new IllegalArgumentException(
15248                    "Call does not support special user #" + targetUserId);
15249        }
15250        // Check shell permission
15251        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15252            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15253                    targetUserId)) {
15254                throw new SecurityException("Shell does not have permission to access user "
15255                        + targetUserId + "\n " + Debug.getCallers(3));
15256            }
15257        }
15258        return targetUserId;
15259    }
15260
15261    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15262            String className, int flags) {
15263        boolean result = false;
15264        // For apps that don't have pre-defined UIDs, check for permission
15265        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15266            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15267                if (ActivityManager.checkUidPermission(
15268                        INTERACT_ACROSS_USERS,
15269                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15270                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15271                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15272                            + " requests FLAG_SINGLE_USER, but app does not hold "
15273                            + INTERACT_ACROSS_USERS;
15274                    Slog.w(TAG, msg);
15275                    throw new SecurityException(msg);
15276                }
15277                // Permission passed
15278                result = true;
15279            }
15280        } else if ("system".equals(componentProcessName)) {
15281            result = true;
15282        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15283            // Phone app and persistent apps are allowed to export singleuser providers.
15284            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15285                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15286        }
15287        if (DEBUG_MU) {
15288            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15289                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15290        }
15291        return result;
15292    }
15293
15294    /**
15295     * Checks to see if the caller is in the same app as the singleton
15296     * component, or the component is in a special app. It allows special apps
15297     * to export singleton components but prevents exporting singleton
15298     * components for regular apps.
15299     */
15300    boolean isValidSingletonCall(int callingUid, int componentUid) {
15301        int componentAppId = UserHandle.getAppId(componentUid);
15302        return UserHandle.isSameApp(callingUid, componentUid)
15303                || componentAppId == Process.SYSTEM_UID
15304                || componentAppId == Process.PHONE_UID
15305                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15306                        == PackageManager.PERMISSION_GRANTED;
15307    }
15308
15309    public int bindService(IApplicationThread caller, IBinder token,
15310            Intent service, String resolvedType,
15311            IServiceConnection connection, int flags, int userId) {
15312        enforceNotIsolatedCaller("bindService");
15313
15314        // Refuse possible leaked file descriptors
15315        if (service != null && service.hasFileDescriptors() == true) {
15316            throw new IllegalArgumentException("File descriptors passed in Intent");
15317        }
15318
15319        synchronized(this) {
15320            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15321                    connection, flags, userId);
15322        }
15323    }
15324
15325    public boolean unbindService(IServiceConnection connection) {
15326        synchronized (this) {
15327            return mServices.unbindServiceLocked(connection);
15328        }
15329    }
15330
15331    public void publishService(IBinder token, Intent intent, IBinder service) {
15332        // Refuse possible leaked file descriptors
15333        if (intent != null && intent.hasFileDescriptors() == true) {
15334            throw new IllegalArgumentException("File descriptors passed in Intent");
15335        }
15336
15337        synchronized(this) {
15338            if (!(token instanceof ServiceRecord)) {
15339                throw new IllegalArgumentException("Invalid service token");
15340            }
15341            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15342        }
15343    }
15344
15345    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15346        // Refuse possible leaked file descriptors
15347        if (intent != null && intent.hasFileDescriptors() == true) {
15348            throw new IllegalArgumentException("File descriptors passed in Intent");
15349        }
15350
15351        synchronized(this) {
15352            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15353        }
15354    }
15355
15356    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15357        synchronized(this) {
15358            if (!(token instanceof ServiceRecord)) {
15359                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15360                throw new IllegalArgumentException("Invalid service token");
15361            }
15362            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15363        }
15364    }
15365
15366    // =========================================================
15367    // BACKUP AND RESTORE
15368    // =========================================================
15369
15370    // Cause the target app to be launched if necessary and its backup agent
15371    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15372    // activity manager to announce its creation.
15373    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15374        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15375        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15376
15377        synchronized(this) {
15378            // !!! TODO: currently no check here that we're already bound
15379            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15380            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15381            synchronized (stats) {
15382                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15383            }
15384
15385            // Backup agent is now in use, its package can't be stopped.
15386            try {
15387                AppGlobals.getPackageManager().setPackageStoppedState(
15388                        app.packageName, false, UserHandle.getUserId(app.uid));
15389            } catch (RemoteException e) {
15390            } catch (IllegalArgumentException e) {
15391                Slog.w(TAG, "Failed trying to unstop package "
15392                        + app.packageName + ": " + e);
15393            }
15394
15395            BackupRecord r = new BackupRecord(ss, app, backupMode);
15396            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15397                    ? new ComponentName(app.packageName, app.backupAgentName)
15398                    : new ComponentName("android", "FullBackupAgent");
15399            // startProcessLocked() returns existing proc's record if it's already running
15400            ProcessRecord proc = startProcessLocked(app.processName, app,
15401                    false, 0, "backup", hostingName, false, false, false);
15402            if (proc == null) {
15403                Slog.e(TAG, "Unable to start backup agent process " + r);
15404                return false;
15405            }
15406
15407            r.app = proc;
15408            mBackupTarget = r;
15409            mBackupAppName = app.packageName;
15410
15411            // Try not to kill the process during backup
15412            updateOomAdjLocked(proc);
15413
15414            // If the process is already attached, schedule the creation of the backup agent now.
15415            // If it is not yet live, this will be done when it attaches to the framework.
15416            if (proc.thread != null) {
15417                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15418                try {
15419                    proc.thread.scheduleCreateBackupAgent(app,
15420                            compatibilityInfoForPackageLocked(app), backupMode);
15421                } catch (RemoteException e) {
15422                    // Will time out on the backup manager side
15423                }
15424            } else {
15425                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15426            }
15427            // Invariants: at this point, the target app process exists and the application
15428            // is either already running or in the process of coming up.  mBackupTarget and
15429            // mBackupAppName describe the app, so that when it binds back to the AM we
15430            // know that it's scheduled for a backup-agent operation.
15431        }
15432
15433        return true;
15434    }
15435
15436    @Override
15437    public void clearPendingBackup() {
15438        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15439        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15440
15441        synchronized (this) {
15442            mBackupTarget = null;
15443            mBackupAppName = null;
15444        }
15445    }
15446
15447    // A backup agent has just come up
15448    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15449        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15450                + " = " + agent);
15451
15452        synchronized(this) {
15453            if (!agentPackageName.equals(mBackupAppName)) {
15454                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15455                return;
15456            }
15457        }
15458
15459        long oldIdent = Binder.clearCallingIdentity();
15460        try {
15461            IBackupManager bm = IBackupManager.Stub.asInterface(
15462                    ServiceManager.getService(Context.BACKUP_SERVICE));
15463            bm.agentConnected(agentPackageName, agent);
15464        } catch (RemoteException e) {
15465            // can't happen; the backup manager service is local
15466        } catch (Exception e) {
15467            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15468            e.printStackTrace();
15469        } finally {
15470            Binder.restoreCallingIdentity(oldIdent);
15471        }
15472    }
15473
15474    // done with this agent
15475    public void unbindBackupAgent(ApplicationInfo appInfo) {
15476        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15477        if (appInfo == null) {
15478            Slog.w(TAG, "unbind backup agent for null app");
15479            return;
15480        }
15481
15482        synchronized(this) {
15483            try {
15484                if (mBackupAppName == null) {
15485                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15486                    return;
15487                }
15488
15489                if (!mBackupAppName.equals(appInfo.packageName)) {
15490                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15491                    return;
15492                }
15493
15494                // Not backing this app up any more; reset its OOM adjustment
15495                final ProcessRecord proc = mBackupTarget.app;
15496                updateOomAdjLocked(proc);
15497
15498                // If the app crashed during backup, 'thread' will be null here
15499                if (proc.thread != null) {
15500                    try {
15501                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15502                                compatibilityInfoForPackageLocked(appInfo));
15503                    } catch (Exception e) {
15504                        Slog.e(TAG, "Exception when unbinding backup agent:");
15505                        e.printStackTrace();
15506                    }
15507                }
15508            } finally {
15509                mBackupTarget = null;
15510                mBackupAppName = null;
15511            }
15512        }
15513    }
15514    // =========================================================
15515    // BROADCASTS
15516    // =========================================================
15517
15518    private final List getStickiesLocked(String action, IntentFilter filter,
15519            List cur, int userId) {
15520        final ContentResolver resolver = mContext.getContentResolver();
15521        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15522        if (stickies == null) {
15523            return cur;
15524        }
15525        final ArrayList<Intent> list = stickies.get(action);
15526        if (list == null) {
15527            return cur;
15528        }
15529        int N = list.size();
15530        for (int i=0; i<N; i++) {
15531            Intent intent = list.get(i);
15532            if (filter.match(resolver, intent, true, TAG) >= 0) {
15533                if (cur == null) {
15534                    cur = new ArrayList<Intent>();
15535                }
15536                cur.add(intent);
15537            }
15538        }
15539        return cur;
15540    }
15541
15542    boolean isPendingBroadcastProcessLocked(int pid) {
15543        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15544                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15545    }
15546
15547    void skipPendingBroadcastLocked(int pid) {
15548            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15549            for (BroadcastQueue queue : mBroadcastQueues) {
15550                queue.skipPendingBroadcastLocked(pid);
15551            }
15552    }
15553
15554    // The app just attached; send any pending broadcasts that it should receive
15555    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15556        boolean didSomething = false;
15557        for (BroadcastQueue queue : mBroadcastQueues) {
15558            didSomething |= queue.sendPendingBroadcastsLocked(app);
15559        }
15560        return didSomething;
15561    }
15562
15563    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15564            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15565        enforceNotIsolatedCaller("registerReceiver");
15566        int callingUid;
15567        int callingPid;
15568        synchronized(this) {
15569            ProcessRecord callerApp = null;
15570            if (caller != null) {
15571                callerApp = getRecordForAppLocked(caller);
15572                if (callerApp == null) {
15573                    throw new SecurityException(
15574                            "Unable to find app for caller " + caller
15575                            + " (pid=" + Binder.getCallingPid()
15576                            + ") when registering receiver " + receiver);
15577                }
15578                if (callerApp.info.uid != Process.SYSTEM_UID &&
15579                        !callerApp.pkgList.containsKey(callerPackage) &&
15580                        !"android".equals(callerPackage)) {
15581                    throw new SecurityException("Given caller package " + callerPackage
15582                            + " is not running in process " + callerApp);
15583                }
15584                callingUid = callerApp.info.uid;
15585                callingPid = callerApp.pid;
15586            } else {
15587                callerPackage = null;
15588                callingUid = Binder.getCallingUid();
15589                callingPid = Binder.getCallingPid();
15590            }
15591
15592            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15593                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15594
15595            List allSticky = null;
15596
15597            // Look for any matching sticky broadcasts...
15598            Iterator actions = filter.actionsIterator();
15599            if (actions != null) {
15600                while (actions.hasNext()) {
15601                    String action = (String)actions.next();
15602                    allSticky = getStickiesLocked(action, filter, allSticky,
15603                            UserHandle.USER_ALL);
15604                    allSticky = getStickiesLocked(action, filter, allSticky,
15605                            UserHandle.getUserId(callingUid));
15606                }
15607            } else {
15608                allSticky = getStickiesLocked(null, filter, allSticky,
15609                        UserHandle.USER_ALL);
15610                allSticky = getStickiesLocked(null, filter, allSticky,
15611                        UserHandle.getUserId(callingUid));
15612            }
15613
15614            // The first sticky in the list is returned directly back to
15615            // the client.
15616            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15617
15618            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15619                    + ": " + sticky);
15620
15621            if (receiver == null) {
15622                return sticky;
15623            }
15624
15625            ReceiverList rl
15626                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15627            if (rl == null) {
15628                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15629                        userId, receiver);
15630                if (rl.app != null) {
15631                    rl.app.receivers.add(rl);
15632                } else {
15633                    try {
15634                        receiver.asBinder().linkToDeath(rl, 0);
15635                    } catch (RemoteException e) {
15636                        return sticky;
15637                    }
15638                    rl.linkedToDeath = true;
15639                }
15640                mRegisteredReceivers.put(receiver.asBinder(), rl);
15641            } else if (rl.uid != callingUid) {
15642                throw new IllegalArgumentException(
15643                        "Receiver requested to register for uid " + callingUid
15644                        + " was previously registered for uid " + rl.uid);
15645            } else if (rl.pid != callingPid) {
15646                throw new IllegalArgumentException(
15647                        "Receiver requested to register for pid " + callingPid
15648                        + " was previously registered for pid " + rl.pid);
15649            } else if (rl.userId != userId) {
15650                throw new IllegalArgumentException(
15651                        "Receiver requested to register for user " + userId
15652                        + " was previously registered for user " + rl.userId);
15653            }
15654            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15655                    permission, callingUid, userId);
15656            rl.add(bf);
15657            if (!bf.debugCheck()) {
15658                Slog.w(TAG, "==> For Dynamic broadast");
15659            }
15660            mReceiverResolver.addFilter(bf);
15661
15662            // Enqueue broadcasts for all existing stickies that match
15663            // this filter.
15664            if (allSticky != null) {
15665                ArrayList receivers = new ArrayList();
15666                receivers.add(bf);
15667
15668                int N = allSticky.size();
15669                for (int i=0; i<N; i++) {
15670                    Intent intent = (Intent)allSticky.get(i);
15671                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15672                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15673                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15674                            null, null, false, true, true, -1);
15675                    queue.enqueueParallelBroadcastLocked(r);
15676                    queue.scheduleBroadcastsLocked();
15677                }
15678            }
15679
15680            return sticky;
15681        }
15682    }
15683
15684    public void unregisterReceiver(IIntentReceiver receiver) {
15685        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15686
15687        final long origId = Binder.clearCallingIdentity();
15688        try {
15689            boolean doTrim = false;
15690
15691            synchronized(this) {
15692                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15693                if (rl != null) {
15694                    if (rl.curBroadcast != null) {
15695                        BroadcastRecord r = rl.curBroadcast;
15696                        final boolean doNext = finishReceiverLocked(
15697                                receiver.asBinder(), r.resultCode, r.resultData,
15698                                r.resultExtras, r.resultAbort);
15699                        if (doNext) {
15700                            doTrim = true;
15701                            r.queue.processNextBroadcast(false);
15702                        }
15703                    }
15704
15705                    if (rl.app != null) {
15706                        rl.app.receivers.remove(rl);
15707                    }
15708                    removeReceiverLocked(rl);
15709                    if (rl.linkedToDeath) {
15710                        rl.linkedToDeath = false;
15711                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15712                    }
15713                }
15714            }
15715
15716            // If we actually concluded any broadcasts, we might now be able
15717            // to trim the recipients' apps from our working set
15718            if (doTrim) {
15719                trimApplications();
15720                return;
15721            }
15722
15723        } finally {
15724            Binder.restoreCallingIdentity(origId);
15725        }
15726    }
15727
15728    void removeReceiverLocked(ReceiverList rl) {
15729        mRegisteredReceivers.remove(rl.receiver.asBinder());
15730        int N = rl.size();
15731        for (int i=0; i<N; i++) {
15732            mReceiverResolver.removeFilter(rl.get(i));
15733        }
15734    }
15735
15736    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15737        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15738            ProcessRecord r = mLruProcesses.get(i);
15739            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15740                try {
15741                    r.thread.dispatchPackageBroadcast(cmd, packages);
15742                } catch (RemoteException ex) {
15743                }
15744            }
15745        }
15746    }
15747
15748    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15749            int callingUid, int[] users) {
15750        List<ResolveInfo> receivers = null;
15751        try {
15752            HashSet<ComponentName> singleUserReceivers = null;
15753            boolean scannedFirstReceivers = false;
15754            for (int user : users) {
15755                // Skip users that have Shell restrictions
15756                if (callingUid == Process.SHELL_UID
15757                        && getUserManagerLocked().hasUserRestriction(
15758                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15759                    continue;
15760                }
15761                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15762                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15763                if (user != 0 && newReceivers != null) {
15764                    // If this is not the primary user, we need to check for
15765                    // any receivers that should be filtered out.
15766                    for (int i=0; i<newReceivers.size(); i++) {
15767                        ResolveInfo ri = newReceivers.get(i);
15768                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15769                            newReceivers.remove(i);
15770                            i--;
15771                        }
15772                    }
15773                }
15774                if (newReceivers != null && newReceivers.size() == 0) {
15775                    newReceivers = null;
15776                }
15777                if (receivers == null) {
15778                    receivers = newReceivers;
15779                } else if (newReceivers != null) {
15780                    // We need to concatenate the additional receivers
15781                    // found with what we have do far.  This would be easy,
15782                    // but we also need to de-dup any receivers that are
15783                    // singleUser.
15784                    if (!scannedFirstReceivers) {
15785                        // Collect any single user receivers we had already retrieved.
15786                        scannedFirstReceivers = true;
15787                        for (int i=0; i<receivers.size(); i++) {
15788                            ResolveInfo ri = receivers.get(i);
15789                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15790                                ComponentName cn = new ComponentName(
15791                                        ri.activityInfo.packageName, ri.activityInfo.name);
15792                                if (singleUserReceivers == null) {
15793                                    singleUserReceivers = new HashSet<ComponentName>();
15794                                }
15795                                singleUserReceivers.add(cn);
15796                            }
15797                        }
15798                    }
15799                    // Add the new results to the existing results, tracking
15800                    // and de-dupping single user receivers.
15801                    for (int i=0; i<newReceivers.size(); i++) {
15802                        ResolveInfo ri = newReceivers.get(i);
15803                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15804                            ComponentName cn = new ComponentName(
15805                                    ri.activityInfo.packageName, ri.activityInfo.name);
15806                            if (singleUserReceivers == null) {
15807                                singleUserReceivers = new HashSet<ComponentName>();
15808                            }
15809                            if (!singleUserReceivers.contains(cn)) {
15810                                singleUserReceivers.add(cn);
15811                                receivers.add(ri);
15812                            }
15813                        } else {
15814                            receivers.add(ri);
15815                        }
15816                    }
15817                }
15818            }
15819        } catch (RemoteException ex) {
15820            // pm is in same process, this will never happen.
15821        }
15822        return receivers;
15823    }
15824
15825    private final int broadcastIntentLocked(ProcessRecord callerApp,
15826            String callerPackage, Intent intent, String resolvedType,
15827            IIntentReceiver resultTo, int resultCode, String resultData,
15828            Bundle map, String requiredPermission, int appOp,
15829            boolean ordered, boolean sticky, int callingPid, int callingUid,
15830            int userId) {
15831        intent = new Intent(intent);
15832
15833        // By default broadcasts do not go to stopped apps.
15834        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15835
15836        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15837            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15838            + " ordered=" + ordered + " userid=" + userId);
15839        if ((resultTo != null) && !ordered) {
15840            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15841        }
15842
15843        userId = handleIncomingUser(callingPid, callingUid, userId,
15844                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15845
15846        // Make sure that the user who is receiving this broadcast is running.
15847        // If not, we will just skip it. Make an exception for shutdown broadcasts
15848        // and upgrade steps.
15849
15850        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15851            if ((callingUid != Process.SYSTEM_UID
15852                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15853                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15854                Slog.w(TAG, "Skipping broadcast of " + intent
15855                        + ": user " + userId + " is stopped");
15856                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15857            }
15858        }
15859
15860        /*
15861         * Prevent non-system code (defined here to be non-persistent
15862         * processes) from sending protected broadcasts.
15863         */
15864        int callingAppId = UserHandle.getAppId(callingUid);
15865        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15866            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15867            || callingAppId == Process.NFC_UID || callingUid == 0) {
15868            // Always okay.
15869        } else if (callerApp == null || !callerApp.persistent) {
15870            try {
15871                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15872                        intent.getAction())) {
15873                    String msg = "Permission Denial: not allowed to send broadcast "
15874                            + intent.getAction() + " from pid="
15875                            + callingPid + ", uid=" + callingUid;
15876                    Slog.w(TAG, msg);
15877                    throw new SecurityException(msg);
15878                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15879                    // Special case for compatibility: we don't want apps to send this,
15880                    // but historically it has not been protected and apps may be using it
15881                    // to poke their own app widget.  So, instead of making it protected,
15882                    // just limit it to the caller.
15883                    if (callerApp == null) {
15884                        String msg = "Permission Denial: not allowed to send broadcast "
15885                                + intent.getAction() + " from unknown caller.";
15886                        Slog.w(TAG, msg);
15887                        throw new SecurityException(msg);
15888                    } else if (intent.getComponent() != null) {
15889                        // They are good enough to send to an explicit component...  verify
15890                        // it is being sent to the calling app.
15891                        if (!intent.getComponent().getPackageName().equals(
15892                                callerApp.info.packageName)) {
15893                            String msg = "Permission Denial: not allowed to send broadcast "
15894                                    + intent.getAction() + " to "
15895                                    + intent.getComponent().getPackageName() + " from "
15896                                    + callerApp.info.packageName;
15897                            Slog.w(TAG, msg);
15898                            throw new SecurityException(msg);
15899                        }
15900                    } else {
15901                        // Limit broadcast to their own package.
15902                        intent.setPackage(callerApp.info.packageName);
15903                    }
15904                }
15905            } catch (RemoteException e) {
15906                Slog.w(TAG, "Remote exception", e);
15907                return ActivityManager.BROADCAST_SUCCESS;
15908            }
15909        }
15910
15911        final String action = intent.getAction();
15912        if (action != null) {
15913            switch (action) {
15914                case Intent.ACTION_UID_REMOVED:
15915                case Intent.ACTION_PACKAGE_REMOVED:
15916                case Intent.ACTION_PACKAGE_CHANGED:
15917                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15918                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15919                    // Handle special intents: if this broadcast is from the package
15920                    // manager about a package being removed, we need to remove all of
15921                    // its activities from the history stack.
15922                    if (checkComponentPermission(
15923                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15924                            callingPid, callingUid, -1, true)
15925                            != PackageManager.PERMISSION_GRANTED) {
15926                        String msg = "Permission Denial: " + intent.getAction()
15927                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15928                                + ", uid=" + callingUid + ")"
15929                                + " requires "
15930                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15931                        Slog.w(TAG, msg);
15932                        throw new SecurityException(msg);
15933                    }
15934                    switch (action) {
15935                        case Intent.ACTION_UID_REMOVED:
15936                            final Bundle intentExtras = intent.getExtras();
15937                            final int uid = intentExtras != null
15938                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15939                            if (uid >= 0) {
15940                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15941                                synchronized (bs) {
15942                                    bs.removeUidStatsLocked(uid);
15943                                }
15944                                mAppOpsService.uidRemoved(uid);
15945                            }
15946                            break;
15947                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15948                            // If resources are unavailable just force stop all those packages
15949                            // and flush the attribute cache as well.
15950                            String list[] =
15951                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15952                            if (list != null && list.length > 0) {
15953                                for (int i = 0; i < list.length; i++) {
15954                                    forceStopPackageLocked(list[i], -1, false, true, true,
15955                                            false, false, userId, "storage unmount");
15956                                }
15957                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15958                                sendPackageBroadcastLocked(
15959                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15960                                        userId);
15961                            }
15962                            break;
15963                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15964                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15965                            break;
15966                        case Intent.ACTION_PACKAGE_REMOVED:
15967                        case Intent.ACTION_PACKAGE_CHANGED:
15968                            Uri data = intent.getData();
15969                            String ssp;
15970                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15971                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15972                                boolean fullUninstall = removed &&
15973                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15974                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15975                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15976                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15977                                            false, true, true, false, fullUninstall, userId,
15978                                            removed ? "pkg removed" : "pkg changed");
15979                                }
15980                                if (removed) {
15981                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15982                                            new String[] {ssp}, userId);
15983                                    if (fullUninstall) {
15984                                        mAppOpsService.packageRemoved(
15985                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15986
15987                                        // Remove all permissions granted from/to this package
15988                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15989
15990                                        removeTasksByPackageNameLocked(ssp, userId);
15991                                        if (userId == UserHandle.USER_OWNER) {
15992                                            mTaskPersister.removeFromPackageCache(ssp);
15993                                        }
15994                                    }
15995                                } else {
15996                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15997                                    if (userId == UserHandle.USER_OWNER) {
15998                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15999                                    }
16000                                }
16001                            }
16002                            break;
16003                    }
16004                    break;
16005                case Intent.ACTION_PACKAGE_ADDED:
16006                    // Special case for adding a package: by default turn on compatibility mode.
16007                    Uri data = intent.getData();
16008                    String ssp;
16009                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16010                        final boolean replacing =
16011                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16012                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16013
16014                        if (replacing) {
16015                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16016                        }
16017                        if (userId == UserHandle.USER_OWNER) {
16018                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16019                        }
16020                    }
16021                    break;
16022                case Intent.ACTION_TIMEZONE_CHANGED:
16023                    // If this is the time zone changed action, queue up a message that will reset
16024                    // the timezone of all currently running processes. This message will get
16025                    // queued up before the broadcast happens.
16026                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16027                    break;
16028                case Intent.ACTION_TIME_CHANGED:
16029                    // If the user set the time, let all running processes know.
16030                    final int is24Hour =
16031                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16032                                    : 0;
16033                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16034                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16035                    synchronized (stats) {
16036                        stats.noteCurrentTimeChangedLocked();
16037                    }
16038                    break;
16039                case Intent.ACTION_CLEAR_DNS_CACHE:
16040                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16041                    break;
16042                case Proxy.PROXY_CHANGE_ACTION:
16043                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16044                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16045                    break;
16046            }
16047        }
16048
16049        // Add to the sticky list if requested.
16050        if (sticky) {
16051            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16052                    callingPid, callingUid)
16053                    != PackageManager.PERMISSION_GRANTED) {
16054                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16055                        + callingPid + ", uid=" + callingUid
16056                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16057                Slog.w(TAG, msg);
16058                throw new SecurityException(msg);
16059            }
16060            if (requiredPermission != null) {
16061                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16062                        + " and enforce permission " + requiredPermission);
16063                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16064            }
16065            if (intent.getComponent() != null) {
16066                throw new SecurityException(
16067                        "Sticky broadcasts can't target a specific component");
16068            }
16069            // We use userId directly here, since the "all" target is maintained
16070            // as a separate set of sticky broadcasts.
16071            if (userId != UserHandle.USER_ALL) {
16072                // But first, if this is not a broadcast to all users, then
16073                // make sure it doesn't conflict with an existing broadcast to
16074                // all users.
16075                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16076                        UserHandle.USER_ALL);
16077                if (stickies != null) {
16078                    ArrayList<Intent> list = stickies.get(intent.getAction());
16079                    if (list != null) {
16080                        int N = list.size();
16081                        int i;
16082                        for (i=0; i<N; i++) {
16083                            if (intent.filterEquals(list.get(i))) {
16084                                throw new IllegalArgumentException(
16085                                        "Sticky broadcast " + intent + " for user "
16086                                        + userId + " conflicts with existing global broadcast");
16087                            }
16088                        }
16089                    }
16090                }
16091            }
16092            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16093            if (stickies == null) {
16094                stickies = new ArrayMap<String, ArrayList<Intent>>();
16095                mStickyBroadcasts.put(userId, stickies);
16096            }
16097            ArrayList<Intent> list = stickies.get(intent.getAction());
16098            if (list == null) {
16099                list = new ArrayList<Intent>();
16100                stickies.put(intent.getAction(), list);
16101            }
16102            int N = list.size();
16103            int i;
16104            for (i=0; i<N; i++) {
16105                if (intent.filterEquals(list.get(i))) {
16106                    // This sticky already exists, replace it.
16107                    list.set(i, new Intent(intent));
16108                    break;
16109                }
16110            }
16111            if (i >= N) {
16112                list.add(new Intent(intent));
16113            }
16114        }
16115
16116        int[] users;
16117        if (userId == UserHandle.USER_ALL) {
16118            // Caller wants broadcast to go to all started users.
16119            users = mStartedUserArray;
16120        } else {
16121            // Caller wants broadcast to go to one specific user.
16122            users = new int[] {userId};
16123        }
16124
16125        // Figure out who all will receive this broadcast.
16126        List receivers = null;
16127        List<BroadcastFilter> registeredReceivers = null;
16128        // Need to resolve the intent to interested receivers...
16129        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16130                 == 0) {
16131            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16132        }
16133        if (intent.getComponent() == null) {
16134            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16135                // Query one target user at a time, excluding shell-restricted users
16136                UserManagerService ums = getUserManagerLocked();
16137                for (int i = 0; i < users.length; i++) {
16138                    if (ums.hasUserRestriction(
16139                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16140                        continue;
16141                    }
16142                    List<BroadcastFilter> registeredReceiversForUser =
16143                            mReceiverResolver.queryIntent(intent,
16144                                    resolvedType, false, users[i]);
16145                    if (registeredReceivers == null) {
16146                        registeredReceivers = registeredReceiversForUser;
16147                    } else if (registeredReceiversForUser != null) {
16148                        registeredReceivers.addAll(registeredReceiversForUser);
16149                    }
16150                }
16151            } else {
16152                registeredReceivers = mReceiverResolver.queryIntent(intent,
16153                        resolvedType, false, userId);
16154            }
16155        }
16156
16157        final boolean replacePending =
16158                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16159
16160        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16161                + " replacePending=" + replacePending);
16162
16163        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16164        if (!ordered && NR > 0) {
16165            // If we are not serializing this broadcast, then send the
16166            // registered receivers separately so they don't wait for the
16167            // components to be launched.
16168            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16169            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16170                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16171                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16172                    ordered, sticky, false, userId);
16173            if (DEBUG_BROADCAST) Slog.v(
16174                    TAG, "Enqueueing parallel broadcast " + r);
16175            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16176            if (!replaced) {
16177                queue.enqueueParallelBroadcastLocked(r);
16178                queue.scheduleBroadcastsLocked();
16179            }
16180            registeredReceivers = null;
16181            NR = 0;
16182        }
16183
16184        // Merge into one list.
16185        int ir = 0;
16186        if (receivers != null) {
16187            // A special case for PACKAGE_ADDED: do not allow the package
16188            // being added to see this broadcast.  This prevents them from
16189            // using this as a back door to get run as soon as they are
16190            // installed.  Maybe in the future we want to have a special install
16191            // broadcast or such for apps, but we'd like to deliberately make
16192            // this decision.
16193            String skipPackages[] = null;
16194            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16195                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16196                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16197                Uri data = intent.getData();
16198                if (data != null) {
16199                    String pkgName = data.getSchemeSpecificPart();
16200                    if (pkgName != null) {
16201                        skipPackages = new String[] { pkgName };
16202                    }
16203                }
16204            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16205                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16206            }
16207            if (skipPackages != null && (skipPackages.length > 0)) {
16208                for (String skipPackage : skipPackages) {
16209                    if (skipPackage != null) {
16210                        int NT = receivers.size();
16211                        for (int it=0; it<NT; it++) {
16212                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16213                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16214                                receivers.remove(it);
16215                                it--;
16216                                NT--;
16217                            }
16218                        }
16219                    }
16220                }
16221            }
16222
16223            int NT = receivers != null ? receivers.size() : 0;
16224            int it = 0;
16225            ResolveInfo curt = null;
16226            BroadcastFilter curr = null;
16227            while (it < NT && ir < NR) {
16228                if (curt == null) {
16229                    curt = (ResolveInfo)receivers.get(it);
16230                }
16231                if (curr == null) {
16232                    curr = registeredReceivers.get(ir);
16233                }
16234                if (curr.getPriority() >= curt.priority) {
16235                    // Insert this broadcast record into the final list.
16236                    receivers.add(it, curr);
16237                    ir++;
16238                    curr = null;
16239                    it++;
16240                    NT++;
16241                } else {
16242                    // Skip to the next ResolveInfo in the final list.
16243                    it++;
16244                    curt = null;
16245                }
16246            }
16247        }
16248        while (ir < NR) {
16249            if (receivers == null) {
16250                receivers = new ArrayList();
16251            }
16252            receivers.add(registeredReceivers.get(ir));
16253            ir++;
16254        }
16255
16256        if ((receivers != null && receivers.size() > 0)
16257                || resultTo != null) {
16258            BroadcastQueue queue = broadcastQueueForIntent(intent);
16259            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16260                    callerPackage, callingPid, callingUid, resolvedType,
16261                    requiredPermission, appOp, receivers, resultTo, resultCode,
16262                    resultData, map, ordered, sticky, false, userId);
16263            if (DEBUG_BROADCAST) Slog.v(
16264                    TAG, "Enqueueing ordered broadcast " + r
16265                    + ": prev had " + queue.mOrderedBroadcasts.size());
16266            if (DEBUG_BROADCAST) {
16267                int seq = r.intent.getIntExtra("seq", -1);
16268                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16269            }
16270            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16271            if (!replaced) {
16272                queue.enqueueOrderedBroadcastLocked(r);
16273                queue.scheduleBroadcastsLocked();
16274            }
16275        }
16276
16277        return ActivityManager.BROADCAST_SUCCESS;
16278    }
16279
16280    final Intent verifyBroadcastLocked(Intent intent) {
16281        // Refuse possible leaked file descriptors
16282        if (intent != null && intent.hasFileDescriptors() == true) {
16283            throw new IllegalArgumentException("File descriptors passed in Intent");
16284        }
16285
16286        int flags = intent.getFlags();
16287
16288        if (!mProcessesReady) {
16289            // if the caller really truly claims to know what they're doing, go
16290            // ahead and allow the broadcast without launching any receivers
16291            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16292                intent = new Intent(intent);
16293                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16294            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16295                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16296                        + " before boot completion");
16297                throw new IllegalStateException("Cannot broadcast before boot completed");
16298            }
16299        }
16300
16301        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16302            throw new IllegalArgumentException(
16303                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16304        }
16305
16306        return intent;
16307    }
16308
16309    public final int broadcastIntent(IApplicationThread caller,
16310            Intent intent, String resolvedType, IIntentReceiver resultTo,
16311            int resultCode, String resultData, Bundle map,
16312            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16313        enforceNotIsolatedCaller("broadcastIntent");
16314        synchronized(this) {
16315            intent = verifyBroadcastLocked(intent);
16316
16317            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16318            final int callingPid = Binder.getCallingPid();
16319            final int callingUid = Binder.getCallingUid();
16320            final long origId = Binder.clearCallingIdentity();
16321            int res = broadcastIntentLocked(callerApp,
16322                    callerApp != null ? callerApp.info.packageName : null,
16323                    intent, resolvedType, resultTo,
16324                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16325                    callingPid, callingUid, userId);
16326            Binder.restoreCallingIdentity(origId);
16327            return res;
16328        }
16329    }
16330
16331    int broadcastIntentInPackage(String packageName, int uid,
16332            Intent intent, String resolvedType, IIntentReceiver resultTo,
16333            int resultCode, String resultData, Bundle map,
16334            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16335        synchronized(this) {
16336            intent = verifyBroadcastLocked(intent);
16337
16338            final long origId = Binder.clearCallingIdentity();
16339            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16340                    resultTo, resultCode, resultData, map, requiredPermission,
16341                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16342            Binder.restoreCallingIdentity(origId);
16343            return res;
16344        }
16345    }
16346
16347    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16348        // Refuse possible leaked file descriptors
16349        if (intent != null && intent.hasFileDescriptors() == true) {
16350            throw new IllegalArgumentException("File descriptors passed in Intent");
16351        }
16352
16353        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16354                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16355
16356        synchronized(this) {
16357            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16358                    != PackageManager.PERMISSION_GRANTED) {
16359                String msg = "Permission Denial: unbroadcastIntent() from pid="
16360                        + Binder.getCallingPid()
16361                        + ", uid=" + Binder.getCallingUid()
16362                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16363                Slog.w(TAG, msg);
16364                throw new SecurityException(msg);
16365            }
16366            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16367            if (stickies != null) {
16368                ArrayList<Intent> list = stickies.get(intent.getAction());
16369                if (list != null) {
16370                    int N = list.size();
16371                    int i;
16372                    for (i=0; i<N; i++) {
16373                        if (intent.filterEquals(list.get(i))) {
16374                            list.remove(i);
16375                            break;
16376                        }
16377                    }
16378                    if (list.size() <= 0) {
16379                        stickies.remove(intent.getAction());
16380                    }
16381                }
16382                if (stickies.size() <= 0) {
16383                    mStickyBroadcasts.remove(userId);
16384                }
16385            }
16386        }
16387    }
16388
16389    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16390            String resultData, Bundle resultExtras, boolean resultAbort) {
16391        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16392        if (r == null) {
16393            Slog.w(TAG, "finishReceiver called but not found on queue");
16394            return false;
16395        }
16396
16397        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16398    }
16399
16400    void backgroundServicesFinishedLocked(int userId) {
16401        for (BroadcastQueue queue : mBroadcastQueues) {
16402            queue.backgroundServicesFinishedLocked(userId);
16403        }
16404    }
16405
16406    public void finishReceiver(IBinder who, int resultCode, String resultData,
16407            Bundle resultExtras, boolean resultAbort) {
16408        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16409
16410        // Refuse possible leaked file descriptors
16411        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16412            throw new IllegalArgumentException("File descriptors passed in Bundle");
16413        }
16414
16415        final long origId = Binder.clearCallingIdentity();
16416        try {
16417            boolean doNext = false;
16418            BroadcastRecord r;
16419
16420            synchronized(this) {
16421                r = broadcastRecordForReceiverLocked(who);
16422                if (r != null) {
16423                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16424                        resultData, resultExtras, resultAbort, true);
16425                }
16426            }
16427
16428            if (doNext) {
16429                r.queue.processNextBroadcast(false);
16430            }
16431            trimApplications();
16432        } finally {
16433            Binder.restoreCallingIdentity(origId);
16434        }
16435    }
16436
16437    // =========================================================
16438    // INSTRUMENTATION
16439    // =========================================================
16440
16441    public boolean startInstrumentation(ComponentName className,
16442            String profileFile, int flags, Bundle arguments,
16443            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16444            int userId, String abiOverride) {
16445        enforceNotIsolatedCaller("startInstrumentation");
16446        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16447                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16448        // Refuse possible leaked file descriptors
16449        if (arguments != null && arguments.hasFileDescriptors()) {
16450            throw new IllegalArgumentException("File descriptors passed in Bundle");
16451        }
16452
16453        synchronized(this) {
16454            InstrumentationInfo ii = null;
16455            ApplicationInfo ai = null;
16456            try {
16457                ii = mContext.getPackageManager().getInstrumentationInfo(
16458                    className, STOCK_PM_FLAGS);
16459                ai = AppGlobals.getPackageManager().getApplicationInfo(
16460                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16461            } catch (PackageManager.NameNotFoundException e) {
16462            } catch (RemoteException e) {
16463            }
16464            if (ii == null) {
16465                reportStartInstrumentationFailure(watcher, className,
16466                        "Unable to find instrumentation info for: " + className);
16467                return false;
16468            }
16469            if (ai == null) {
16470                reportStartInstrumentationFailure(watcher, className,
16471                        "Unable to find instrumentation target package: " + ii.targetPackage);
16472                return false;
16473            }
16474
16475            int match = mContext.getPackageManager().checkSignatures(
16476                    ii.targetPackage, ii.packageName);
16477            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16478                String msg = "Permission Denial: starting instrumentation "
16479                        + className + " from pid="
16480                        + Binder.getCallingPid()
16481                        + ", uid=" + Binder.getCallingPid()
16482                        + " not allowed because package " + ii.packageName
16483                        + " does not have a signature matching the target "
16484                        + ii.targetPackage;
16485                reportStartInstrumentationFailure(watcher, className, msg);
16486                throw new SecurityException(msg);
16487            }
16488
16489            final long origId = Binder.clearCallingIdentity();
16490            // Instrumentation can kill and relaunch even persistent processes
16491            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16492                    "start instr");
16493            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16494            app.instrumentationClass = className;
16495            app.instrumentationInfo = ai;
16496            app.instrumentationProfileFile = profileFile;
16497            app.instrumentationArguments = arguments;
16498            app.instrumentationWatcher = watcher;
16499            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16500            app.instrumentationResultClass = className;
16501            Binder.restoreCallingIdentity(origId);
16502        }
16503
16504        return true;
16505    }
16506
16507    /**
16508     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16509     * error to the logs, but if somebody is watching, send the report there too.  This enables
16510     * the "am" command to report errors with more information.
16511     *
16512     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16513     * @param cn The component name of the instrumentation.
16514     * @param report The error report.
16515     */
16516    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16517            ComponentName cn, String report) {
16518        Slog.w(TAG, report);
16519        try {
16520            if (watcher != null) {
16521                Bundle results = new Bundle();
16522                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16523                results.putString("Error", report);
16524                watcher.instrumentationStatus(cn, -1, results);
16525            }
16526        } catch (RemoteException e) {
16527            Slog.w(TAG, e);
16528        }
16529    }
16530
16531    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16532        if (app.instrumentationWatcher != null) {
16533            try {
16534                // NOTE:  IInstrumentationWatcher *must* be oneway here
16535                app.instrumentationWatcher.instrumentationFinished(
16536                    app.instrumentationClass,
16537                    resultCode,
16538                    results);
16539            } catch (RemoteException e) {
16540            }
16541        }
16542        if (app.instrumentationUiAutomationConnection != null) {
16543            try {
16544                app.instrumentationUiAutomationConnection.shutdown();
16545            } catch (RemoteException re) {
16546                /* ignore */
16547            }
16548            // Only a UiAutomation can set this flag and now that
16549            // it is finished we make sure it is reset to its default.
16550            mUserIsMonkey = false;
16551        }
16552        app.instrumentationWatcher = null;
16553        app.instrumentationUiAutomationConnection = null;
16554        app.instrumentationClass = null;
16555        app.instrumentationInfo = null;
16556        app.instrumentationProfileFile = null;
16557        app.instrumentationArguments = null;
16558
16559        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16560                "finished inst");
16561    }
16562
16563    public void finishInstrumentation(IApplicationThread target,
16564            int resultCode, Bundle results) {
16565        int userId = UserHandle.getCallingUserId();
16566        // Refuse possible leaked file descriptors
16567        if (results != null && results.hasFileDescriptors()) {
16568            throw new IllegalArgumentException("File descriptors passed in Intent");
16569        }
16570
16571        synchronized(this) {
16572            ProcessRecord app = getRecordForAppLocked(target);
16573            if (app == null) {
16574                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16575                return;
16576            }
16577            final long origId = Binder.clearCallingIdentity();
16578            finishInstrumentationLocked(app, resultCode, results);
16579            Binder.restoreCallingIdentity(origId);
16580        }
16581    }
16582
16583    // =========================================================
16584    // CONFIGURATION
16585    // =========================================================
16586
16587    public ConfigurationInfo getDeviceConfigurationInfo() {
16588        ConfigurationInfo config = new ConfigurationInfo();
16589        synchronized (this) {
16590            config.reqTouchScreen = mConfiguration.touchscreen;
16591            config.reqKeyboardType = mConfiguration.keyboard;
16592            config.reqNavigation = mConfiguration.navigation;
16593            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16594                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16595                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16596            }
16597            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16598                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16599                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16600            }
16601            config.reqGlEsVersion = GL_ES_VERSION;
16602        }
16603        return config;
16604    }
16605
16606    ActivityStack getFocusedStack() {
16607        return mStackSupervisor.getFocusedStack();
16608    }
16609
16610    public Configuration getConfiguration() {
16611        Configuration ci;
16612        synchronized(this) {
16613            ci = new Configuration(mConfiguration);
16614            ci.userSetLocale = false;
16615        }
16616        return ci;
16617    }
16618
16619    public void updatePersistentConfiguration(Configuration values) {
16620        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16621                "updateConfiguration()");
16622        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16623                "updateConfiguration()");
16624        if (values == null) {
16625            throw new NullPointerException("Configuration must not be null");
16626        }
16627
16628        synchronized(this) {
16629            final long origId = Binder.clearCallingIdentity();
16630            updateConfigurationLocked(values, null, true, false);
16631            Binder.restoreCallingIdentity(origId);
16632        }
16633    }
16634
16635    public void updateConfiguration(Configuration values) {
16636        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16637                "updateConfiguration()");
16638
16639        synchronized(this) {
16640            if (values == null && mWindowManager != null) {
16641                // sentinel: fetch the current configuration from the window manager
16642                values = mWindowManager.computeNewConfiguration();
16643            }
16644
16645            if (mWindowManager != null) {
16646                mProcessList.applyDisplaySize(mWindowManager);
16647            }
16648
16649            final long origId = Binder.clearCallingIdentity();
16650            if (values != null) {
16651                Settings.System.clearConfiguration(values);
16652            }
16653            updateConfigurationLocked(values, null, false, false);
16654            Binder.restoreCallingIdentity(origId);
16655        }
16656    }
16657
16658    /**
16659     * Do either or both things: (1) change the current configuration, and (2)
16660     * make sure the given activity is running with the (now) current
16661     * configuration.  Returns true if the activity has been left running, or
16662     * false if <var>starting</var> is being destroyed to match the new
16663     * configuration.
16664     * @param persistent TODO
16665     */
16666    boolean updateConfigurationLocked(Configuration values,
16667            ActivityRecord starting, boolean persistent, boolean initLocale) {
16668        int changes = 0;
16669
16670        if (values != null) {
16671            Configuration newConfig = new Configuration(mConfiguration);
16672            changes = newConfig.updateFrom(values);
16673            if (changes != 0) {
16674                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16675                    Slog.i(TAG, "Updating configuration to: " + values);
16676                }
16677
16678                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16679
16680                if (values.locale != null && !initLocale) {
16681                    saveLocaleLocked(values.locale,
16682                                     !values.locale.equals(mConfiguration.locale),
16683                                     values.userSetLocale);
16684                }
16685
16686                mConfigurationSeq++;
16687                if (mConfigurationSeq <= 0) {
16688                    mConfigurationSeq = 1;
16689                }
16690                newConfig.seq = mConfigurationSeq;
16691                mConfiguration = newConfig;
16692                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16693                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16694                //mUsageStatsService.noteStartConfig(newConfig);
16695
16696                final Configuration configCopy = new Configuration(mConfiguration);
16697
16698                // TODO: If our config changes, should we auto dismiss any currently
16699                // showing dialogs?
16700                mShowDialogs = shouldShowDialogs(newConfig);
16701
16702                AttributeCache ac = AttributeCache.instance();
16703                if (ac != null) {
16704                    ac.updateConfiguration(configCopy);
16705                }
16706
16707                // Make sure all resources in our process are updated
16708                // right now, so that anyone who is going to retrieve
16709                // resource values after we return will be sure to get
16710                // the new ones.  This is especially important during
16711                // boot, where the first config change needs to guarantee
16712                // all resources have that config before following boot
16713                // code is executed.
16714                mSystemThread.applyConfigurationToResources(configCopy);
16715
16716                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16717                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16718                    msg.obj = new Configuration(configCopy);
16719                    mHandler.sendMessage(msg);
16720                }
16721
16722                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16723                    ProcessRecord app = mLruProcesses.get(i);
16724                    try {
16725                        if (app.thread != null) {
16726                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16727                                    + app.processName + " new config " + mConfiguration);
16728                            app.thread.scheduleConfigurationChanged(configCopy);
16729                        }
16730                    } catch (Exception e) {
16731                    }
16732                }
16733                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16734                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16735                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16736                        | Intent.FLAG_RECEIVER_FOREGROUND);
16737                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16738                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16739                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16740                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16741                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16742                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16743                    broadcastIntentLocked(null, null, intent,
16744                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16745                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16746                }
16747            }
16748        }
16749
16750        boolean kept = true;
16751        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16752        // mainStack is null during startup.
16753        if (mainStack != null) {
16754            if (changes != 0 && starting == null) {
16755                // If the configuration changed, and the caller is not already
16756                // in the process of starting an activity, then find the top
16757                // activity to check if its configuration needs to change.
16758                starting = mainStack.topRunningActivityLocked(null);
16759            }
16760
16761            if (starting != null) {
16762                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16763                // And we need to make sure at this point that all other activities
16764                // are made visible with the correct configuration.
16765                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16766            }
16767        }
16768
16769        if (values != null && mWindowManager != null) {
16770            mWindowManager.setNewConfiguration(mConfiguration);
16771        }
16772
16773        return kept;
16774    }
16775
16776    /**
16777     * Decide based on the configuration whether we should shouw the ANR,
16778     * crash, etc dialogs.  The idea is that if there is no affordnace to
16779     * press the on-screen buttons, we shouldn't show the dialog.
16780     *
16781     * A thought: SystemUI might also want to get told about this, the Power
16782     * dialog / global actions also might want different behaviors.
16783     */
16784    private static final boolean shouldShowDialogs(Configuration config) {
16785        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16786                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16787    }
16788
16789    /**
16790     * Save the locale.  You must be inside a synchronized (this) block.
16791     */
16792    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16793        if(isDiff) {
16794            SystemProperties.set("user.language", l.getLanguage());
16795            SystemProperties.set("user.region", l.getCountry());
16796        }
16797
16798        if(isPersist) {
16799            SystemProperties.set("persist.sys.language", l.getLanguage());
16800            SystemProperties.set("persist.sys.country", l.getCountry());
16801            SystemProperties.set("persist.sys.localevar", l.getVariant());
16802
16803            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16804        }
16805    }
16806
16807    @Override
16808    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16809        synchronized (this) {
16810            ActivityRecord srec = ActivityRecord.forToken(token);
16811            if (srec.task != null && srec.task.stack != null) {
16812                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16813            }
16814        }
16815        return false;
16816    }
16817
16818    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16819            Intent resultData) {
16820
16821        synchronized (this) {
16822            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16823            if (stack != null) {
16824                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16825            }
16826            return false;
16827        }
16828    }
16829
16830    public int getLaunchedFromUid(IBinder activityToken) {
16831        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16832        if (srec == null) {
16833            return -1;
16834        }
16835        return srec.launchedFromUid;
16836    }
16837
16838    public String getLaunchedFromPackage(IBinder activityToken) {
16839        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16840        if (srec == null) {
16841            return null;
16842        }
16843        return srec.launchedFromPackage;
16844    }
16845
16846    // =========================================================
16847    // LIFETIME MANAGEMENT
16848    // =========================================================
16849
16850    // Returns which broadcast queue the app is the current [or imminent] receiver
16851    // on, or 'null' if the app is not an active broadcast recipient.
16852    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16853        BroadcastRecord r = app.curReceiver;
16854        if (r != null) {
16855            return r.queue;
16856        }
16857
16858        // It's not the current receiver, but it might be starting up to become one
16859        synchronized (this) {
16860            for (BroadcastQueue queue : mBroadcastQueues) {
16861                r = queue.mPendingBroadcast;
16862                if (r != null && r.curApp == app) {
16863                    // found it; report which queue it's in
16864                    return queue;
16865                }
16866            }
16867        }
16868
16869        return null;
16870    }
16871
16872    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16873            ComponentName targetComponent, String targetProcess) {
16874        if (!mTrackingAssociations) {
16875            return null;
16876        }
16877        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16878                = mAssociations.get(targetUid);
16879        if (components == null) {
16880            components = new ArrayMap<>();
16881            mAssociations.put(targetUid, components);
16882        }
16883        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16884        if (sourceUids == null) {
16885            sourceUids = new SparseArray<>();
16886            components.put(targetComponent, sourceUids);
16887        }
16888        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16889        if (sourceProcesses == null) {
16890            sourceProcesses = new ArrayMap<>();
16891            sourceUids.put(sourceUid, sourceProcesses);
16892        }
16893        Association ass = sourceProcesses.get(sourceProcess);
16894        if (ass == null) {
16895            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16896                    targetProcess);
16897            sourceProcesses.put(sourceProcess, ass);
16898        }
16899        ass.mCount++;
16900        ass.mNesting++;
16901        if (ass.mNesting == 1) {
16902            ass.mStartTime = SystemClock.uptimeMillis();
16903        }
16904        return ass;
16905    }
16906
16907    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16908            ComponentName targetComponent) {
16909        if (!mTrackingAssociations) {
16910            return;
16911        }
16912        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16913                = mAssociations.get(targetUid);
16914        if (components == null) {
16915            return;
16916        }
16917        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16918        if (sourceUids == null) {
16919            return;
16920        }
16921        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16922        if (sourceProcesses == null) {
16923            return;
16924        }
16925        Association ass = sourceProcesses.get(sourceProcess);
16926        if (ass == null || ass.mNesting <= 0) {
16927            return;
16928        }
16929        ass.mNesting--;
16930        if (ass.mNesting == 0) {
16931            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16932        }
16933    }
16934
16935    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16936            boolean doingAll, long now) {
16937        if (mAdjSeq == app.adjSeq) {
16938            // This adjustment has already been computed.
16939            return app.curRawAdj;
16940        }
16941
16942        if (app.thread == null) {
16943            app.adjSeq = mAdjSeq;
16944            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16945            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16946            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16947        }
16948
16949        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16950        app.adjSource = null;
16951        app.adjTarget = null;
16952        app.empty = false;
16953        app.cached = false;
16954
16955        final int activitiesSize = app.activities.size();
16956
16957        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16958            // The max adjustment doesn't allow this app to be anything
16959            // below foreground, so it is not worth doing work for it.
16960            app.adjType = "fixed";
16961            app.adjSeq = mAdjSeq;
16962            app.curRawAdj = app.maxAdj;
16963            app.foregroundActivities = false;
16964            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16965            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16966            // System processes can do UI, and when they do we want to have
16967            // them trim their memory after the user leaves the UI.  To
16968            // facilitate this, here we need to determine whether or not it
16969            // is currently showing UI.
16970            app.systemNoUi = true;
16971            if (app == TOP_APP) {
16972                app.systemNoUi = false;
16973            } else if (activitiesSize > 0) {
16974                for (int j = 0; j < activitiesSize; j++) {
16975                    final ActivityRecord r = app.activities.get(j);
16976                    if (r.visible) {
16977                        app.systemNoUi = false;
16978                    }
16979                }
16980            }
16981            if (!app.systemNoUi) {
16982                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16983            }
16984            return (app.curAdj=app.maxAdj);
16985        }
16986
16987        app.systemNoUi = false;
16988
16989        // Determine the importance of the process, starting with most
16990        // important to least, and assign an appropriate OOM adjustment.
16991        int adj;
16992        int schedGroup;
16993        int procState;
16994        boolean foregroundActivities = false;
16995        BroadcastQueue queue;
16996        if (app == TOP_APP) {
16997            // The last app on the list is the foreground app.
16998            adj = ProcessList.FOREGROUND_APP_ADJ;
16999            schedGroup = Process.THREAD_GROUP_DEFAULT;
17000            app.adjType = "top-activity";
17001            foregroundActivities = true;
17002            procState = ActivityManager.PROCESS_STATE_TOP;
17003        } else if (app.instrumentationClass != null) {
17004            // Don't want to kill running instrumentation.
17005            adj = ProcessList.FOREGROUND_APP_ADJ;
17006            schedGroup = Process.THREAD_GROUP_DEFAULT;
17007            app.adjType = "instrumentation";
17008            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17009        } else if ((queue = isReceivingBroadcast(app)) != null) {
17010            // An app that is currently receiving a broadcast also
17011            // counts as being in the foreground for OOM killer purposes.
17012            // It's placed in a sched group based on the nature of the
17013            // broadcast as reflected by which queue it's active in.
17014            adj = ProcessList.FOREGROUND_APP_ADJ;
17015            schedGroup = (queue == mFgBroadcastQueue)
17016                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17017            app.adjType = "broadcast";
17018            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17019        } else if (app.executingServices.size() > 0) {
17020            // An app that is currently executing a service callback also
17021            // counts as being in the foreground.
17022            adj = ProcessList.FOREGROUND_APP_ADJ;
17023            schedGroup = app.execServicesFg ?
17024                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17025            app.adjType = "exec-service";
17026            procState = ActivityManager.PROCESS_STATE_SERVICE;
17027            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17028        } else {
17029            // As far as we know the process is empty.  We may change our mind later.
17030            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17031            // At this point we don't actually know the adjustment.  Use the cached adj
17032            // value that the caller wants us to.
17033            adj = cachedAdj;
17034            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17035            app.cached = true;
17036            app.empty = true;
17037            app.adjType = "cch-empty";
17038        }
17039
17040        // Examine all activities if not already foreground.
17041        if (!foregroundActivities && activitiesSize > 0) {
17042            for (int j = 0; j < activitiesSize; j++) {
17043                final ActivityRecord r = app.activities.get(j);
17044                if (r.app != app) {
17045                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17046                            + app + "?!?");
17047                    continue;
17048                }
17049                if (r.visible) {
17050                    // App has a visible activity; only upgrade adjustment.
17051                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17052                        adj = ProcessList.VISIBLE_APP_ADJ;
17053                        app.adjType = "visible";
17054                    }
17055                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17056                        procState = ActivityManager.PROCESS_STATE_TOP;
17057                    }
17058                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17059                    app.cached = false;
17060                    app.empty = false;
17061                    foregroundActivities = true;
17062                    break;
17063                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17064                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17065                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17066                        app.adjType = "pausing";
17067                    }
17068                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17069                        procState = ActivityManager.PROCESS_STATE_TOP;
17070                    }
17071                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17072                    app.cached = false;
17073                    app.empty = false;
17074                    foregroundActivities = true;
17075                } else if (r.state == ActivityState.STOPPING) {
17076                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17077                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17078                        app.adjType = "stopping";
17079                    }
17080                    // For the process state, we will at this point consider the
17081                    // process to be cached.  It will be cached either as an activity
17082                    // or empty depending on whether the activity is finishing.  We do
17083                    // this so that we can treat the process as cached for purposes of
17084                    // memory trimming (determing current memory level, trim command to
17085                    // send to process) since there can be an arbitrary number of stopping
17086                    // processes and they should soon all go into the cached state.
17087                    if (!r.finishing) {
17088                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17089                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17090                        }
17091                    }
17092                    app.cached = false;
17093                    app.empty = false;
17094                    foregroundActivities = true;
17095                } else {
17096                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17097                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17098                        app.adjType = "cch-act";
17099                    }
17100                }
17101            }
17102        }
17103
17104        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17105            if (app.foregroundServices) {
17106                // The user is aware of this app, so make it visible.
17107                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17108                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17109                app.cached = false;
17110                app.adjType = "fg-service";
17111                schedGroup = Process.THREAD_GROUP_DEFAULT;
17112            } else if (app.forcingToForeground != null) {
17113                // The user is aware of this app, so make it visible.
17114                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17115                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17116                app.cached = false;
17117                app.adjType = "force-fg";
17118                app.adjSource = app.forcingToForeground;
17119                schedGroup = Process.THREAD_GROUP_DEFAULT;
17120            }
17121        }
17122
17123        if (app == mHeavyWeightProcess) {
17124            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17125                // We don't want to kill the current heavy-weight process.
17126                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17127                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17128                app.cached = false;
17129                app.adjType = "heavy";
17130            }
17131            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17132                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17133            }
17134        }
17135
17136        if (app == mHomeProcess) {
17137            if (adj > ProcessList.HOME_APP_ADJ) {
17138                // This process is hosting what we currently consider to be the
17139                // home app, so we don't want to let it go into the background.
17140                adj = ProcessList.HOME_APP_ADJ;
17141                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17142                app.cached = false;
17143                app.adjType = "home";
17144            }
17145            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17146                procState = ActivityManager.PROCESS_STATE_HOME;
17147            }
17148        }
17149
17150        if (app == mPreviousProcess && app.activities.size() > 0) {
17151            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17152                // This was the previous process that showed UI to the user.
17153                // We want to try to keep it around more aggressively, to give
17154                // a good experience around switching between two apps.
17155                adj = ProcessList.PREVIOUS_APP_ADJ;
17156                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17157                app.cached = false;
17158                app.adjType = "previous";
17159            }
17160            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17161                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17162            }
17163        }
17164
17165        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17166                + " reason=" + app.adjType);
17167
17168        // By default, we use the computed adjustment.  It may be changed if
17169        // there are applications dependent on our services or providers, but
17170        // this gives us a baseline and makes sure we don't get into an
17171        // infinite recursion.
17172        app.adjSeq = mAdjSeq;
17173        app.curRawAdj = adj;
17174        app.hasStartedServices = false;
17175
17176        if (mBackupTarget != null && app == mBackupTarget.app) {
17177            // If possible we want to avoid killing apps while they're being backed up
17178            if (adj > ProcessList.BACKUP_APP_ADJ) {
17179                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17180                adj = ProcessList.BACKUP_APP_ADJ;
17181                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17182                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17183                }
17184                app.adjType = "backup";
17185                app.cached = false;
17186            }
17187            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17188                procState = ActivityManager.PROCESS_STATE_BACKUP;
17189            }
17190        }
17191
17192        boolean mayBeTop = false;
17193
17194        for (int is = app.services.size()-1;
17195                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17196                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17197                        || procState > ActivityManager.PROCESS_STATE_TOP);
17198                is--) {
17199            ServiceRecord s = app.services.valueAt(is);
17200            if (s.startRequested) {
17201                app.hasStartedServices = true;
17202                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17203                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17204                }
17205                if (app.hasShownUi && app != mHomeProcess) {
17206                    // If this process has shown some UI, let it immediately
17207                    // go to the LRU list because it may be pretty heavy with
17208                    // UI stuff.  We'll tag it with a label just to help
17209                    // debug and understand what is going on.
17210                    if (adj > ProcessList.SERVICE_ADJ) {
17211                        app.adjType = "cch-started-ui-services";
17212                    }
17213                } else {
17214                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17215                        // This service has seen some activity within
17216                        // recent memory, so we will keep its process ahead
17217                        // of the background processes.
17218                        if (adj > ProcessList.SERVICE_ADJ) {
17219                            adj = ProcessList.SERVICE_ADJ;
17220                            app.adjType = "started-services";
17221                            app.cached = false;
17222                        }
17223                    }
17224                    // If we have let the service slide into the background
17225                    // state, still have some text describing what it is doing
17226                    // even though the service no longer has an impact.
17227                    if (adj > ProcessList.SERVICE_ADJ) {
17228                        app.adjType = "cch-started-services";
17229                    }
17230                }
17231            }
17232            for (int conni = s.connections.size()-1;
17233                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17234                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17235                            || procState > ActivityManager.PROCESS_STATE_TOP);
17236                    conni--) {
17237                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17238                for (int i = 0;
17239                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17240                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17241                                || procState > ActivityManager.PROCESS_STATE_TOP);
17242                        i++) {
17243                    // XXX should compute this based on the max of
17244                    // all connected clients.
17245                    ConnectionRecord cr = clist.get(i);
17246                    if (cr.binding.client == app) {
17247                        // Binding to ourself is not interesting.
17248                        continue;
17249                    }
17250                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17251                        ProcessRecord client = cr.binding.client;
17252                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17253                                TOP_APP, doingAll, now);
17254                        int clientProcState = client.curProcState;
17255                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17256                            // If the other app is cached for any reason, for purposes here
17257                            // we are going to consider it empty.  The specific cached state
17258                            // doesn't propagate except under certain conditions.
17259                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17260                        }
17261                        String adjType = null;
17262                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17263                            // Not doing bind OOM management, so treat
17264                            // this guy more like a started service.
17265                            if (app.hasShownUi && app != mHomeProcess) {
17266                                // If this process has shown some UI, let it immediately
17267                                // go to the LRU list because it may be pretty heavy with
17268                                // UI stuff.  We'll tag it with a label just to help
17269                                // debug and understand what is going on.
17270                                if (adj > clientAdj) {
17271                                    adjType = "cch-bound-ui-services";
17272                                }
17273                                app.cached = false;
17274                                clientAdj = adj;
17275                                clientProcState = procState;
17276                            } else {
17277                                if (now >= (s.lastActivity
17278                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17279                                    // This service has not seen activity within
17280                                    // recent memory, so allow it to drop to the
17281                                    // LRU list if there is no other reason to keep
17282                                    // it around.  We'll also tag it with a label just
17283                                    // to help debug and undertand what is going on.
17284                                    if (adj > clientAdj) {
17285                                        adjType = "cch-bound-services";
17286                                    }
17287                                    clientAdj = adj;
17288                                }
17289                            }
17290                        }
17291                        if (adj > clientAdj) {
17292                            // If this process has recently shown UI, and
17293                            // the process that is binding to it is less
17294                            // important than being visible, then we don't
17295                            // care about the binding as much as we care
17296                            // about letting this process get into the LRU
17297                            // list to be killed and restarted if needed for
17298                            // memory.
17299                            if (app.hasShownUi && app != mHomeProcess
17300                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17301                                adjType = "cch-bound-ui-services";
17302                            } else {
17303                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17304                                        |Context.BIND_IMPORTANT)) != 0) {
17305                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17306                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17307                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17308                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17309                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17310                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17311                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17312                                    adj = clientAdj;
17313                                } else {
17314                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17315                                        adj = ProcessList.VISIBLE_APP_ADJ;
17316                                    }
17317                                }
17318                                if (!client.cached) {
17319                                    app.cached = false;
17320                                }
17321                                adjType = "service";
17322                            }
17323                        }
17324                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17325                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17326                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17327                            }
17328                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17329                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17330                                    // Special handling of clients who are in the top state.
17331                                    // We *may* want to consider this process to be in the
17332                                    // top state as well, but only if there is not another
17333                                    // reason for it to be running.  Being on the top is a
17334                                    // special state, meaning you are specifically running
17335                                    // for the current top app.  If the process is already
17336                                    // running in the background for some other reason, it
17337                                    // is more important to continue considering it to be
17338                                    // in the background state.
17339                                    mayBeTop = true;
17340                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17341                                } else {
17342                                    // Special handling for above-top states (persistent
17343                                    // processes).  These should not bring the current process
17344                                    // into the top state, since they are not on top.  Instead
17345                                    // give them the best state after that.
17346                                    clientProcState =
17347                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17348                                }
17349                            }
17350                        } else {
17351                            if (clientProcState <
17352                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17353                                clientProcState =
17354                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17355                            }
17356                        }
17357                        if (procState > clientProcState) {
17358                            procState = clientProcState;
17359                        }
17360                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17361                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17362                            app.pendingUiClean = true;
17363                        }
17364                        if (adjType != null) {
17365                            app.adjType = adjType;
17366                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17367                                    .REASON_SERVICE_IN_USE;
17368                            app.adjSource = cr.binding.client;
17369                            app.adjSourceProcState = clientProcState;
17370                            app.adjTarget = s.name;
17371                        }
17372                    }
17373                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17374                        app.treatLikeActivity = true;
17375                    }
17376                    final ActivityRecord a = cr.activity;
17377                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17378                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17379                                (a.visible || a.state == ActivityState.RESUMED
17380                                 || a.state == ActivityState.PAUSING)) {
17381                            adj = ProcessList.FOREGROUND_APP_ADJ;
17382                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17383                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17384                            }
17385                            app.cached = false;
17386                            app.adjType = "service";
17387                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17388                                    .REASON_SERVICE_IN_USE;
17389                            app.adjSource = a;
17390                            app.adjSourceProcState = procState;
17391                            app.adjTarget = s.name;
17392                        }
17393                    }
17394                }
17395            }
17396        }
17397
17398        for (int provi = app.pubProviders.size()-1;
17399                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17400                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17401                        || procState > ActivityManager.PROCESS_STATE_TOP);
17402                provi--) {
17403            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17404            for (int i = cpr.connections.size()-1;
17405                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17406                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17407                            || procState > ActivityManager.PROCESS_STATE_TOP);
17408                    i--) {
17409                ContentProviderConnection conn = cpr.connections.get(i);
17410                ProcessRecord client = conn.client;
17411                if (client == app) {
17412                    // Being our own client is not interesting.
17413                    continue;
17414                }
17415                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17416                int clientProcState = client.curProcState;
17417                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17418                    // If the other app is cached for any reason, for purposes here
17419                    // we are going to consider it empty.
17420                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17421                }
17422                if (adj > clientAdj) {
17423                    if (app.hasShownUi && app != mHomeProcess
17424                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17425                        app.adjType = "cch-ui-provider";
17426                    } else {
17427                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17428                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17429                        app.adjType = "provider";
17430                    }
17431                    app.cached &= client.cached;
17432                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17433                            .REASON_PROVIDER_IN_USE;
17434                    app.adjSource = client;
17435                    app.adjSourceProcState = clientProcState;
17436                    app.adjTarget = cpr.name;
17437                }
17438                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17439                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17440                        // Special handling of clients who are in the top state.
17441                        // We *may* want to consider this process to be in the
17442                        // top state as well, but only if there is not another
17443                        // reason for it to be running.  Being on the top is a
17444                        // special state, meaning you are specifically running
17445                        // for the current top app.  If the process is already
17446                        // running in the background for some other reason, it
17447                        // is more important to continue considering it to be
17448                        // in the background state.
17449                        mayBeTop = true;
17450                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17451                    } else {
17452                        // Special handling for above-top states (persistent
17453                        // processes).  These should not bring the current process
17454                        // into the top state, since they are not on top.  Instead
17455                        // give them the best state after that.
17456                        clientProcState =
17457                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17458                    }
17459                }
17460                if (procState > clientProcState) {
17461                    procState = clientProcState;
17462                }
17463                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17464                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17465                }
17466            }
17467            // If the provider has external (non-framework) process
17468            // dependencies, ensure that its adjustment is at least
17469            // FOREGROUND_APP_ADJ.
17470            if (cpr.hasExternalProcessHandles()) {
17471                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17472                    adj = ProcessList.FOREGROUND_APP_ADJ;
17473                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17474                    app.cached = false;
17475                    app.adjType = "provider";
17476                    app.adjTarget = cpr.name;
17477                }
17478                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17479                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17480                }
17481            }
17482        }
17483
17484        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17485            // A client of one of our services or providers is in the top state.  We
17486            // *may* want to be in the top state, but not if we are already running in
17487            // the background for some other reason.  For the decision here, we are going
17488            // to pick out a few specific states that we want to remain in when a client
17489            // is top (states that tend to be longer-term) and otherwise allow it to go
17490            // to the top state.
17491            switch (procState) {
17492                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17493                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17494                case ActivityManager.PROCESS_STATE_SERVICE:
17495                    // These all are longer-term states, so pull them up to the top
17496                    // of the background states, but not all the way to the top state.
17497                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17498                    break;
17499                default:
17500                    // Otherwise, top is a better choice, so take it.
17501                    procState = ActivityManager.PROCESS_STATE_TOP;
17502                    break;
17503            }
17504        }
17505
17506        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17507            if (app.hasClientActivities) {
17508                // This is a cached process, but with client activities.  Mark it so.
17509                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17510                app.adjType = "cch-client-act";
17511            } else if (app.treatLikeActivity) {
17512                // This is a cached process, but somebody wants us to treat it like it has
17513                // an activity, okay!
17514                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17515                app.adjType = "cch-as-act";
17516            }
17517        }
17518
17519        if (adj == ProcessList.SERVICE_ADJ) {
17520            if (doingAll) {
17521                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17522                mNewNumServiceProcs++;
17523                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17524                if (!app.serviceb) {
17525                    // This service isn't far enough down on the LRU list to
17526                    // normally be a B service, but if we are low on RAM and it
17527                    // is large we want to force it down since we would prefer to
17528                    // keep launcher over it.
17529                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17530                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17531                        app.serviceHighRam = true;
17532                        app.serviceb = true;
17533                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17534                    } else {
17535                        mNewNumAServiceProcs++;
17536                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17537                    }
17538                } else {
17539                    app.serviceHighRam = false;
17540                }
17541            }
17542            if (app.serviceb) {
17543                adj = ProcessList.SERVICE_B_ADJ;
17544            }
17545        }
17546
17547        app.curRawAdj = adj;
17548
17549        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17550        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17551        if (adj > app.maxAdj) {
17552            adj = app.maxAdj;
17553            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17554                schedGroup = Process.THREAD_GROUP_DEFAULT;
17555            }
17556        }
17557
17558        // Do final modification to adj.  Everything we do between here and applying
17559        // the final setAdj must be done in this function, because we will also use
17560        // it when computing the final cached adj later.  Note that we don't need to
17561        // worry about this for max adj above, since max adj will always be used to
17562        // keep it out of the cached vaues.
17563        app.curAdj = app.modifyRawOomAdj(adj);
17564        app.curSchedGroup = schedGroup;
17565        app.curProcState = procState;
17566        app.foregroundActivities = foregroundActivities;
17567
17568        return app.curRawAdj;
17569    }
17570
17571    /**
17572     * Record new PSS sample for a process.
17573     */
17574    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17575        proc.lastPssTime = now;
17576        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17577        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17578                + ": " + pss + " lastPss=" + proc.lastPss
17579                + " state=" + ProcessList.makeProcStateString(procState));
17580        if (proc.initialIdlePss == 0) {
17581            proc.initialIdlePss = pss;
17582        }
17583        proc.lastPss = pss;
17584        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17585            proc.lastCachedPss = pss;
17586        }
17587    }
17588
17589    /**
17590     * Schedule PSS collection of a process.
17591     */
17592    void requestPssLocked(ProcessRecord proc, int procState) {
17593        if (mPendingPssProcesses.contains(proc)) {
17594            return;
17595        }
17596        if (mPendingPssProcesses.size() == 0) {
17597            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17598        }
17599        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17600        proc.pssProcState = procState;
17601        mPendingPssProcesses.add(proc);
17602    }
17603
17604    /**
17605     * Schedule PSS collection of all processes.
17606     */
17607    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17608        if (!always) {
17609            if (now < (mLastFullPssTime +
17610                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17611                return;
17612            }
17613        }
17614        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17615        mLastFullPssTime = now;
17616        mFullPssPending = true;
17617        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17618        mPendingPssProcesses.clear();
17619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17620            ProcessRecord app = mLruProcesses.get(i);
17621            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17622                app.pssProcState = app.setProcState;
17623                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17624                        mTestPssMode, isSleeping(), now);
17625                mPendingPssProcesses.add(app);
17626            }
17627        }
17628        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17629    }
17630
17631    public void setTestPssMode(boolean enabled) {
17632        synchronized (this) {
17633            mTestPssMode = enabled;
17634            if (enabled) {
17635                // Whenever we enable the mode, we want to take a snapshot all of current
17636                // process mem use.
17637                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17638            }
17639        }
17640    }
17641
17642    /**
17643     * Ask a given process to GC right now.
17644     */
17645    final void performAppGcLocked(ProcessRecord app) {
17646        try {
17647            app.lastRequestedGc = SystemClock.uptimeMillis();
17648            if (app.thread != null) {
17649                if (app.reportLowMemory) {
17650                    app.reportLowMemory = false;
17651                    app.thread.scheduleLowMemory();
17652                } else {
17653                    app.thread.processInBackground();
17654                }
17655            }
17656        } catch (Exception e) {
17657            // whatever.
17658        }
17659    }
17660
17661    /**
17662     * Returns true if things are idle enough to perform GCs.
17663     */
17664    private final boolean canGcNowLocked() {
17665        boolean processingBroadcasts = false;
17666        for (BroadcastQueue q : mBroadcastQueues) {
17667            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17668                processingBroadcasts = true;
17669            }
17670        }
17671        return !processingBroadcasts
17672                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17673    }
17674
17675    /**
17676     * Perform GCs on all processes that are waiting for it, but only
17677     * if things are idle.
17678     */
17679    final void performAppGcsLocked() {
17680        final int N = mProcessesToGc.size();
17681        if (N <= 0) {
17682            return;
17683        }
17684        if (canGcNowLocked()) {
17685            while (mProcessesToGc.size() > 0) {
17686                ProcessRecord proc = mProcessesToGc.remove(0);
17687                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17688                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17689                            <= SystemClock.uptimeMillis()) {
17690                        // To avoid spamming the system, we will GC processes one
17691                        // at a time, waiting a few seconds between each.
17692                        performAppGcLocked(proc);
17693                        scheduleAppGcsLocked();
17694                        return;
17695                    } else {
17696                        // It hasn't been long enough since we last GCed this
17697                        // process...  put it in the list to wait for its time.
17698                        addProcessToGcListLocked(proc);
17699                        break;
17700                    }
17701                }
17702            }
17703
17704            scheduleAppGcsLocked();
17705        }
17706    }
17707
17708    /**
17709     * If all looks good, perform GCs on all processes waiting for them.
17710     */
17711    final void performAppGcsIfAppropriateLocked() {
17712        if (canGcNowLocked()) {
17713            performAppGcsLocked();
17714            return;
17715        }
17716        // Still not idle, wait some more.
17717        scheduleAppGcsLocked();
17718    }
17719
17720    /**
17721     * Schedule the execution of all pending app GCs.
17722     */
17723    final void scheduleAppGcsLocked() {
17724        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17725
17726        if (mProcessesToGc.size() > 0) {
17727            // Schedule a GC for the time to the next process.
17728            ProcessRecord proc = mProcessesToGc.get(0);
17729            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17730
17731            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17732            long now = SystemClock.uptimeMillis();
17733            if (when < (now+GC_TIMEOUT)) {
17734                when = now + GC_TIMEOUT;
17735            }
17736            mHandler.sendMessageAtTime(msg, when);
17737        }
17738    }
17739
17740    /**
17741     * Add a process to the array of processes waiting to be GCed.  Keeps the
17742     * list in sorted order by the last GC time.  The process can't already be
17743     * on the list.
17744     */
17745    final void addProcessToGcListLocked(ProcessRecord proc) {
17746        boolean added = false;
17747        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17748            if (mProcessesToGc.get(i).lastRequestedGc <
17749                    proc.lastRequestedGc) {
17750                added = true;
17751                mProcessesToGc.add(i+1, proc);
17752                break;
17753            }
17754        }
17755        if (!added) {
17756            mProcessesToGc.add(0, proc);
17757        }
17758    }
17759
17760    /**
17761     * Set up to ask a process to GC itself.  This will either do it
17762     * immediately, or put it on the list of processes to gc the next
17763     * time things are idle.
17764     */
17765    final void scheduleAppGcLocked(ProcessRecord app) {
17766        long now = SystemClock.uptimeMillis();
17767        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17768            return;
17769        }
17770        if (!mProcessesToGc.contains(app)) {
17771            addProcessToGcListLocked(app);
17772            scheduleAppGcsLocked();
17773        }
17774    }
17775
17776    final void checkExcessivePowerUsageLocked(boolean doKills) {
17777        updateCpuStatsNow();
17778
17779        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17780        boolean doWakeKills = doKills;
17781        boolean doCpuKills = doKills;
17782        if (mLastPowerCheckRealtime == 0) {
17783            doWakeKills = false;
17784        }
17785        if (mLastPowerCheckUptime == 0) {
17786            doCpuKills = false;
17787        }
17788        if (stats.isScreenOn()) {
17789            doWakeKills = false;
17790        }
17791        final long curRealtime = SystemClock.elapsedRealtime();
17792        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17793        final long curUptime = SystemClock.uptimeMillis();
17794        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17795        mLastPowerCheckRealtime = curRealtime;
17796        mLastPowerCheckUptime = curUptime;
17797        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17798            doWakeKills = false;
17799        }
17800        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17801            doCpuKills = false;
17802        }
17803        int i = mLruProcesses.size();
17804        while (i > 0) {
17805            i--;
17806            ProcessRecord app = mLruProcesses.get(i);
17807            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17808                long wtime;
17809                synchronized (stats) {
17810                    wtime = stats.getProcessWakeTime(app.info.uid,
17811                            app.pid, curRealtime);
17812                }
17813                long wtimeUsed = wtime - app.lastWakeTime;
17814                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17815                if (DEBUG_POWER) {
17816                    StringBuilder sb = new StringBuilder(128);
17817                    sb.append("Wake for ");
17818                    app.toShortString(sb);
17819                    sb.append(": over ");
17820                    TimeUtils.formatDuration(realtimeSince, sb);
17821                    sb.append(" used ");
17822                    TimeUtils.formatDuration(wtimeUsed, sb);
17823                    sb.append(" (");
17824                    sb.append((wtimeUsed*100)/realtimeSince);
17825                    sb.append("%)");
17826                    Slog.i(TAG, sb.toString());
17827                    sb.setLength(0);
17828                    sb.append("CPU for ");
17829                    app.toShortString(sb);
17830                    sb.append(": over ");
17831                    TimeUtils.formatDuration(uptimeSince, sb);
17832                    sb.append(" used ");
17833                    TimeUtils.formatDuration(cputimeUsed, sb);
17834                    sb.append(" (");
17835                    sb.append((cputimeUsed*100)/uptimeSince);
17836                    sb.append("%)");
17837                    Slog.i(TAG, sb.toString());
17838                }
17839                // If a process has held a wake lock for more
17840                // than 50% of the time during this period,
17841                // that sounds bad.  Kill!
17842                if (doWakeKills && realtimeSince > 0
17843                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17844                    synchronized (stats) {
17845                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17846                                realtimeSince, wtimeUsed);
17847                    }
17848                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17849                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17850                } else if (doCpuKills && uptimeSince > 0
17851                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17852                    synchronized (stats) {
17853                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17854                                uptimeSince, cputimeUsed);
17855                    }
17856                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17857                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17858                } else {
17859                    app.lastWakeTime = wtime;
17860                    app.lastCpuTime = app.curCpuTime;
17861                }
17862            }
17863        }
17864    }
17865
17866    private final boolean applyOomAdjLocked(ProcessRecord app,
17867            ProcessRecord TOP_APP, boolean doingAll, long now) {
17868        boolean success = true;
17869
17870        if (app.curRawAdj != app.setRawAdj) {
17871            app.setRawAdj = app.curRawAdj;
17872        }
17873
17874        int changes = 0;
17875
17876        if (app.curAdj != app.setAdj) {
17877            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17878            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17879                TAG, "Set " + app.pid + " " + app.processName +
17880                " adj " + app.curAdj + ": " + app.adjType);
17881            app.setAdj = app.curAdj;
17882        }
17883
17884        if (app.setSchedGroup != app.curSchedGroup) {
17885            app.setSchedGroup = app.curSchedGroup;
17886            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17887                    "Setting process group of " + app.processName
17888                    + " to " + app.curSchedGroup);
17889            if (app.waitingToKill != null &&
17890                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17891                app.kill(app.waitingToKill, true);
17892                success = false;
17893            } else {
17894                if (true) {
17895                    long oldId = Binder.clearCallingIdentity();
17896                    try {
17897                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17898                    } catch (Exception e) {
17899                        Slog.w(TAG, "Failed setting process group of " + app.pid
17900                                + " to " + app.curSchedGroup);
17901                        e.printStackTrace();
17902                    } finally {
17903                        Binder.restoreCallingIdentity(oldId);
17904                    }
17905                } else {
17906                    if (app.thread != null) {
17907                        try {
17908                            app.thread.setSchedulingGroup(app.curSchedGroup);
17909                        } catch (RemoteException e) {
17910                        }
17911                    }
17912                }
17913                Process.setSwappiness(app.pid,
17914                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17915            }
17916        }
17917        if (app.repForegroundActivities != app.foregroundActivities) {
17918            app.repForegroundActivities = app.foregroundActivities;
17919            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17920        }
17921        if (app.repProcState != app.curProcState) {
17922            app.repProcState = app.curProcState;
17923            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17924            if (app.thread != null) {
17925                try {
17926                    if (false) {
17927                        //RuntimeException h = new RuntimeException("here");
17928                        Slog.i(TAG, "Sending new process state " + app.repProcState
17929                                + " to " + app /*, h*/);
17930                    }
17931                    app.thread.setProcessState(app.repProcState);
17932                } catch (RemoteException e) {
17933                }
17934            }
17935        }
17936        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17937                app.setProcState)) {
17938            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17939                // Experimental code to more aggressively collect pss while
17940                // running test...  the problem is that this tends to collect
17941                // the data right when a process is transitioning between process
17942                // states, which well tend to give noisy data.
17943                long start = SystemClock.uptimeMillis();
17944                long pss = Debug.getPss(app.pid, mTmpLong, null);
17945                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17946                mPendingPssProcesses.remove(app);
17947                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17948                        + " to " + app.curProcState + ": "
17949                        + (SystemClock.uptimeMillis()-start) + "ms");
17950            }
17951            app.lastStateTime = now;
17952            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17953                    mTestPssMode, isSleeping(), now);
17954            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17955                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17956                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17957                    + (app.nextPssTime-now) + ": " + app);
17958        } else {
17959            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17960                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17961                    mTestPssMode)))) {
17962                requestPssLocked(app, app.setProcState);
17963                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17964                        mTestPssMode, isSleeping(), now);
17965            } else if (false && DEBUG_PSS) {
17966                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17967            }
17968        }
17969        if (app.setProcState != app.curProcState) {
17970            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17971                    "Proc state change of " + app.processName
17972                    + " to " + app.curProcState);
17973            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17974            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17975            if (setImportant && !curImportant) {
17976                // This app is no longer something we consider important enough to allow to
17977                // use arbitrary amounts of battery power.  Note
17978                // its current wake lock time to later know to kill it if
17979                // it is not behaving well.
17980                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17981                synchronized (stats) {
17982                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17983                            app.pid, SystemClock.elapsedRealtime());
17984                }
17985                app.lastCpuTime = app.curCpuTime;
17986
17987            }
17988            app.setProcState = app.curProcState;
17989            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17990                app.notCachedSinceIdle = false;
17991            }
17992            if (!doingAll) {
17993                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17994            } else {
17995                app.procStateChanged = true;
17996            }
17997        }
17998
17999        if (changes != 0) {
18000            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18001            int i = mPendingProcessChanges.size()-1;
18002            ProcessChangeItem item = null;
18003            while (i >= 0) {
18004                item = mPendingProcessChanges.get(i);
18005                if (item.pid == app.pid) {
18006                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18007                    break;
18008                }
18009                i--;
18010            }
18011            if (i < 0) {
18012                // No existing item in pending changes; need a new one.
18013                final int NA = mAvailProcessChanges.size();
18014                if (NA > 0) {
18015                    item = mAvailProcessChanges.remove(NA-1);
18016                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18017                } else {
18018                    item = new ProcessChangeItem();
18019                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18020                }
18021                item.changes = 0;
18022                item.pid = app.pid;
18023                item.uid = app.info.uid;
18024                if (mPendingProcessChanges.size() == 0) {
18025                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18026                            "*** Enqueueing dispatch processes changed!");
18027                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18028                }
18029                mPendingProcessChanges.add(item);
18030            }
18031            item.changes |= changes;
18032            item.processState = app.repProcState;
18033            item.foregroundActivities = app.repForegroundActivities;
18034            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18035                    + Integer.toHexString(System.identityHashCode(item))
18036                    + " " + app.toShortString() + ": changes=" + item.changes
18037                    + " procState=" + item.processState
18038                    + " foreground=" + item.foregroundActivities
18039                    + " type=" + app.adjType + " source=" + app.adjSource
18040                    + " target=" + app.adjTarget);
18041        }
18042
18043        return success;
18044    }
18045
18046    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18047        if (proc.thread != null) {
18048            if (proc.baseProcessTracker != null) {
18049                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18050            }
18051            if (proc.repProcState >= 0) {
18052                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18053                        proc.repProcState);
18054            }
18055        }
18056    }
18057
18058    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18059            ProcessRecord TOP_APP, boolean doingAll, long now) {
18060        if (app.thread == null) {
18061            return false;
18062        }
18063
18064        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18065
18066        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18067    }
18068
18069    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18070            boolean oomAdj) {
18071        if (isForeground != proc.foregroundServices) {
18072            proc.foregroundServices = isForeground;
18073            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18074                    proc.info.uid);
18075            if (isForeground) {
18076                if (curProcs == null) {
18077                    curProcs = new ArrayList<ProcessRecord>();
18078                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18079                }
18080                if (!curProcs.contains(proc)) {
18081                    curProcs.add(proc);
18082                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18083                            proc.info.packageName, proc.info.uid);
18084                }
18085            } else {
18086                if (curProcs != null) {
18087                    if (curProcs.remove(proc)) {
18088                        mBatteryStatsService.noteEvent(
18089                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18090                                proc.info.packageName, proc.info.uid);
18091                        if (curProcs.size() <= 0) {
18092                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18093                        }
18094                    }
18095                }
18096            }
18097            if (oomAdj) {
18098                updateOomAdjLocked();
18099            }
18100        }
18101    }
18102
18103    private final ActivityRecord resumedAppLocked() {
18104        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18105        String pkg;
18106        int uid;
18107        if (act != null) {
18108            pkg = act.packageName;
18109            uid = act.info.applicationInfo.uid;
18110        } else {
18111            pkg = null;
18112            uid = -1;
18113        }
18114        // Has the UID or resumed package name changed?
18115        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18116                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18117            if (mCurResumedPackage != null) {
18118                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18119                        mCurResumedPackage, mCurResumedUid);
18120            }
18121            mCurResumedPackage = pkg;
18122            mCurResumedUid = uid;
18123            if (mCurResumedPackage != null) {
18124                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18125                        mCurResumedPackage, mCurResumedUid);
18126            }
18127        }
18128        return act;
18129    }
18130
18131    final boolean updateOomAdjLocked(ProcessRecord app) {
18132        final ActivityRecord TOP_ACT = resumedAppLocked();
18133        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18134        final boolean wasCached = app.cached;
18135
18136        mAdjSeq++;
18137
18138        // This is the desired cached adjusment we want to tell it to use.
18139        // If our app is currently cached, we know it, and that is it.  Otherwise,
18140        // we don't know it yet, and it needs to now be cached we will then
18141        // need to do a complete oom adj.
18142        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18143                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18144        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18145                SystemClock.uptimeMillis());
18146        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18147            // Changed to/from cached state, so apps after it in the LRU
18148            // list may also be changed.
18149            updateOomAdjLocked();
18150        }
18151        return success;
18152    }
18153
18154    final void updateOomAdjLocked() {
18155        final ActivityRecord TOP_ACT = resumedAppLocked();
18156        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18157        final long now = SystemClock.uptimeMillis();
18158        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18159        final int N = mLruProcesses.size();
18160
18161        if (false) {
18162            RuntimeException e = new RuntimeException();
18163            e.fillInStackTrace();
18164            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18165        }
18166
18167        mAdjSeq++;
18168        mNewNumServiceProcs = 0;
18169        mNewNumAServiceProcs = 0;
18170
18171        final int emptyProcessLimit;
18172        final int cachedProcessLimit;
18173        if (mProcessLimit <= 0) {
18174            emptyProcessLimit = cachedProcessLimit = 0;
18175        } else if (mProcessLimit == 1) {
18176            emptyProcessLimit = 1;
18177            cachedProcessLimit = 0;
18178        } else {
18179            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18180            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18181        }
18182
18183        // Let's determine how many processes we have running vs.
18184        // how many slots we have for background processes; we may want
18185        // to put multiple processes in a slot of there are enough of
18186        // them.
18187        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18188                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18189        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18190        if (numEmptyProcs > cachedProcessLimit) {
18191            // If there are more empty processes than our limit on cached
18192            // processes, then use the cached process limit for the factor.
18193            // This ensures that the really old empty processes get pushed
18194            // down to the bottom, so if we are running low on memory we will
18195            // have a better chance at keeping around more cached processes
18196            // instead of a gazillion empty processes.
18197            numEmptyProcs = cachedProcessLimit;
18198        }
18199        int emptyFactor = numEmptyProcs/numSlots;
18200        if (emptyFactor < 1) emptyFactor = 1;
18201        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18202        if (cachedFactor < 1) cachedFactor = 1;
18203        int stepCached = 0;
18204        int stepEmpty = 0;
18205        int numCached = 0;
18206        int numEmpty = 0;
18207        int numTrimming = 0;
18208
18209        mNumNonCachedProcs = 0;
18210        mNumCachedHiddenProcs = 0;
18211
18212        // First update the OOM adjustment for each of the
18213        // application processes based on their current state.
18214        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18215        int nextCachedAdj = curCachedAdj+1;
18216        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18217        int nextEmptyAdj = curEmptyAdj+2;
18218        for (int i=N-1; i>=0; i--) {
18219            ProcessRecord app = mLruProcesses.get(i);
18220            if (!app.killedByAm && app.thread != null) {
18221                app.procStateChanged = false;
18222                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18223
18224                // If we haven't yet assigned the final cached adj
18225                // to the process, do that now.
18226                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18227                    switch (app.curProcState) {
18228                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18229                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18230                            // This process is a cached process holding activities...
18231                            // assign it the next cached value for that type, and then
18232                            // step that cached level.
18233                            app.curRawAdj = curCachedAdj;
18234                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18235                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18236                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18237                                    + ")");
18238                            if (curCachedAdj != nextCachedAdj) {
18239                                stepCached++;
18240                                if (stepCached >= cachedFactor) {
18241                                    stepCached = 0;
18242                                    curCachedAdj = nextCachedAdj;
18243                                    nextCachedAdj += 2;
18244                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18245                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18246                                    }
18247                                }
18248                            }
18249                            break;
18250                        default:
18251                            // For everything else, assign next empty cached process
18252                            // level and bump that up.  Note that this means that
18253                            // long-running services that have dropped down to the
18254                            // cached level will be treated as empty (since their process
18255                            // state is still as a service), which is what we want.
18256                            app.curRawAdj = curEmptyAdj;
18257                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18258                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18259                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18260                                    + ")");
18261                            if (curEmptyAdj != nextEmptyAdj) {
18262                                stepEmpty++;
18263                                if (stepEmpty >= emptyFactor) {
18264                                    stepEmpty = 0;
18265                                    curEmptyAdj = nextEmptyAdj;
18266                                    nextEmptyAdj += 2;
18267                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18268                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18269                                    }
18270                                }
18271                            }
18272                            break;
18273                    }
18274                }
18275
18276                applyOomAdjLocked(app, TOP_APP, true, now);
18277
18278                // Count the number of process types.
18279                switch (app.curProcState) {
18280                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18281                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18282                        mNumCachedHiddenProcs++;
18283                        numCached++;
18284                        if (numCached > cachedProcessLimit) {
18285                            app.kill("cached #" + numCached, true);
18286                        }
18287                        break;
18288                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18289                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18290                                && app.lastActivityTime < oldTime) {
18291                            app.kill("empty for "
18292                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18293                                    / 1000) + "s", true);
18294                        } else {
18295                            numEmpty++;
18296                            if (numEmpty > emptyProcessLimit) {
18297                                app.kill("empty #" + numEmpty, true);
18298                            }
18299                        }
18300                        break;
18301                    default:
18302                        mNumNonCachedProcs++;
18303                        break;
18304                }
18305
18306                if (app.isolated && app.services.size() <= 0) {
18307                    // If this is an isolated process, and there are no
18308                    // services running in it, then the process is no longer
18309                    // needed.  We agressively kill these because we can by
18310                    // definition not re-use the same process again, and it is
18311                    // good to avoid having whatever code was running in them
18312                    // left sitting around after no longer needed.
18313                    app.kill("isolated not needed", true);
18314                }
18315
18316                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18317                        && !app.killedByAm) {
18318                    numTrimming++;
18319                }
18320            }
18321        }
18322
18323        mNumServiceProcs = mNewNumServiceProcs;
18324
18325        // Now determine the memory trimming level of background processes.
18326        // Unfortunately we need to start at the back of the list to do this
18327        // properly.  We only do this if the number of background apps we
18328        // are managing to keep around is less than half the maximum we desire;
18329        // if we are keeping a good number around, we'll let them use whatever
18330        // memory they want.
18331        final int numCachedAndEmpty = numCached + numEmpty;
18332        int memFactor;
18333        if (numCached <= ProcessList.TRIM_CACHED_APPS
18334                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18335            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18336                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18337            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18338                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18339            } else {
18340                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18341            }
18342        } else {
18343            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18344        }
18345        // We always allow the memory level to go up (better).  We only allow it to go
18346        // down if we are in a state where that is allowed, *and* the total number of processes
18347        // has gone down since last time.
18348        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18349                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18350                + " last=" + mLastNumProcesses);
18351        if (memFactor > mLastMemoryLevel) {
18352            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18353                memFactor = mLastMemoryLevel;
18354                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18355            }
18356        }
18357        mLastMemoryLevel = memFactor;
18358        mLastNumProcesses = mLruProcesses.size();
18359        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18360        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18361        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18362            if (mLowRamStartTime == 0) {
18363                mLowRamStartTime = now;
18364            }
18365            int step = 0;
18366            int fgTrimLevel;
18367            switch (memFactor) {
18368                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18369                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18370                    break;
18371                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18372                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18373                    break;
18374                default:
18375                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18376                    break;
18377            }
18378            int factor = numTrimming/3;
18379            int minFactor = 2;
18380            if (mHomeProcess != null) minFactor++;
18381            if (mPreviousProcess != null) minFactor++;
18382            if (factor < minFactor) factor = minFactor;
18383            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18384            for (int i=N-1; i>=0; i--) {
18385                ProcessRecord app = mLruProcesses.get(i);
18386                if (allChanged || app.procStateChanged) {
18387                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18388                    app.procStateChanged = false;
18389                }
18390                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18391                        && !app.killedByAm) {
18392                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18393                        try {
18394                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18395                                    "Trimming memory of " + app.processName
18396                                    + " to " + curLevel);
18397                            app.thread.scheduleTrimMemory(curLevel);
18398                        } catch (RemoteException e) {
18399                        }
18400                        if (false) {
18401                            // For now we won't do this; our memory trimming seems
18402                            // to be good enough at this point that destroying
18403                            // activities causes more harm than good.
18404                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18405                                    && app != mHomeProcess && app != mPreviousProcess) {
18406                                // Need to do this on its own message because the stack may not
18407                                // be in a consistent state at this point.
18408                                // For these apps we will also finish their activities
18409                                // to help them free memory.
18410                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18411                            }
18412                        }
18413                    }
18414                    app.trimMemoryLevel = curLevel;
18415                    step++;
18416                    if (step >= factor) {
18417                        step = 0;
18418                        switch (curLevel) {
18419                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18420                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18421                                break;
18422                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18423                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18424                                break;
18425                        }
18426                    }
18427                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18428                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18429                            && app.thread != null) {
18430                        try {
18431                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18432                                    "Trimming memory of heavy-weight " + app.processName
18433                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18434                            app.thread.scheduleTrimMemory(
18435                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18436                        } catch (RemoteException e) {
18437                        }
18438                    }
18439                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18440                } else {
18441                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18442                            || app.systemNoUi) && app.pendingUiClean) {
18443                        // If this application is now in the background and it
18444                        // had done UI, then give it the special trim level to
18445                        // have it free UI resources.
18446                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18447                        if (app.trimMemoryLevel < level && app.thread != null) {
18448                            try {
18449                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18450                                        "Trimming memory of bg-ui " + app.processName
18451                                        + " to " + level);
18452                                app.thread.scheduleTrimMemory(level);
18453                            } catch (RemoteException e) {
18454                            }
18455                        }
18456                        app.pendingUiClean = false;
18457                    }
18458                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18459                        try {
18460                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18461                                    "Trimming memory of fg " + app.processName
18462                                    + " to " + fgTrimLevel);
18463                            app.thread.scheduleTrimMemory(fgTrimLevel);
18464                        } catch (RemoteException e) {
18465                        }
18466                    }
18467                    app.trimMemoryLevel = fgTrimLevel;
18468                }
18469            }
18470        } else {
18471            if (mLowRamStartTime != 0) {
18472                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18473                mLowRamStartTime = 0;
18474            }
18475            for (int i=N-1; i>=0; i--) {
18476                ProcessRecord app = mLruProcesses.get(i);
18477                if (allChanged || app.procStateChanged) {
18478                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18479                    app.procStateChanged = false;
18480                }
18481                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18482                        || app.systemNoUi) && app.pendingUiClean) {
18483                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18484                            && app.thread != null) {
18485                        try {
18486                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18487                                    "Trimming memory of ui hidden " + app.processName
18488                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18489                            app.thread.scheduleTrimMemory(
18490                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18491                        } catch (RemoteException e) {
18492                        }
18493                    }
18494                    app.pendingUiClean = false;
18495                }
18496                app.trimMemoryLevel = 0;
18497            }
18498        }
18499
18500        if (mAlwaysFinishActivities) {
18501            // Need to do this on its own message because the stack may not
18502            // be in a consistent state at this point.
18503            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18504        }
18505
18506        if (allChanged) {
18507            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18508        }
18509
18510        if (mProcessStats.shouldWriteNowLocked(now)) {
18511            mHandler.post(new Runnable() {
18512                @Override public void run() {
18513                    synchronized (ActivityManagerService.this) {
18514                        mProcessStats.writeStateAsyncLocked();
18515                    }
18516                }
18517            });
18518        }
18519
18520        if (DEBUG_OOM_ADJ) {
18521            if (false) {
18522                RuntimeException here = new RuntimeException("here");
18523                here.fillInStackTrace();
18524                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18525            } else {
18526                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18527            }
18528        }
18529    }
18530
18531    final void trimApplications() {
18532        synchronized (this) {
18533            int i;
18534
18535            // First remove any unused application processes whose package
18536            // has been removed.
18537            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18538                final ProcessRecord app = mRemovedProcesses.get(i);
18539                if (app.activities.size() == 0
18540                        && app.curReceiver == null && app.services.size() == 0) {
18541                    Slog.i(
18542                        TAG, "Exiting empty application process "
18543                        + app.processName + " ("
18544                        + (app.thread != null ? app.thread.asBinder() : null)
18545                        + ")\n");
18546                    if (app.pid > 0 && app.pid != MY_PID) {
18547                        app.kill("empty", false);
18548                    } else {
18549                        try {
18550                            app.thread.scheduleExit();
18551                        } catch (Exception e) {
18552                            // Ignore exceptions.
18553                        }
18554                    }
18555                    cleanUpApplicationRecordLocked(app, false, true, -1);
18556                    mRemovedProcesses.remove(i);
18557
18558                    if (app.persistent) {
18559                        addAppLocked(app.info, false, null /* ABI override */);
18560                    }
18561                }
18562            }
18563
18564            // Now update the oom adj for all processes.
18565            updateOomAdjLocked();
18566        }
18567    }
18568
18569    /** This method sends the specified signal to each of the persistent apps */
18570    public void signalPersistentProcesses(int sig) throws RemoteException {
18571        if (sig != Process.SIGNAL_USR1) {
18572            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18573        }
18574
18575        synchronized (this) {
18576            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18577                    != PackageManager.PERMISSION_GRANTED) {
18578                throw new SecurityException("Requires permission "
18579                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18580            }
18581
18582            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18583                ProcessRecord r = mLruProcesses.get(i);
18584                if (r.thread != null && r.persistent) {
18585                    Process.sendSignal(r.pid, sig);
18586                }
18587            }
18588        }
18589    }
18590
18591    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18592        if (proc == null || proc == mProfileProc) {
18593            proc = mProfileProc;
18594            profileType = mProfileType;
18595            clearProfilerLocked();
18596        }
18597        if (proc == null) {
18598            return;
18599        }
18600        try {
18601            proc.thread.profilerControl(false, null, profileType);
18602        } catch (RemoteException e) {
18603            throw new IllegalStateException("Process disappeared");
18604        }
18605    }
18606
18607    private void clearProfilerLocked() {
18608        if (mProfileFd != null) {
18609            try {
18610                mProfileFd.close();
18611            } catch (IOException e) {
18612            }
18613        }
18614        mProfileApp = null;
18615        mProfileProc = null;
18616        mProfileFile = null;
18617        mProfileType = 0;
18618        mAutoStopProfiler = false;
18619        mSamplingInterval = 0;
18620    }
18621
18622    public boolean profileControl(String process, int userId, boolean start,
18623            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18624
18625        try {
18626            synchronized (this) {
18627                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18628                // its own permission.
18629                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18630                        != PackageManager.PERMISSION_GRANTED) {
18631                    throw new SecurityException("Requires permission "
18632                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18633                }
18634
18635                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18636                    throw new IllegalArgumentException("null profile info or fd");
18637                }
18638
18639                ProcessRecord proc = null;
18640                if (process != null) {
18641                    proc = findProcessLocked(process, userId, "profileControl");
18642                }
18643
18644                if (start && (proc == null || proc.thread == null)) {
18645                    throw new IllegalArgumentException("Unknown process: " + process);
18646                }
18647
18648                if (start) {
18649                    stopProfilerLocked(null, 0);
18650                    setProfileApp(proc.info, proc.processName, profilerInfo);
18651                    mProfileProc = proc;
18652                    mProfileType = profileType;
18653                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18654                    try {
18655                        fd = fd.dup();
18656                    } catch (IOException e) {
18657                        fd = null;
18658                    }
18659                    profilerInfo.profileFd = fd;
18660                    proc.thread.profilerControl(start, profilerInfo, profileType);
18661                    fd = null;
18662                    mProfileFd = null;
18663                } else {
18664                    stopProfilerLocked(proc, profileType);
18665                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18666                        try {
18667                            profilerInfo.profileFd.close();
18668                        } catch (IOException e) {
18669                        }
18670                    }
18671                }
18672
18673                return true;
18674            }
18675        } catch (RemoteException e) {
18676            throw new IllegalStateException("Process disappeared");
18677        } finally {
18678            if (profilerInfo != null && profilerInfo.profileFd != null) {
18679                try {
18680                    profilerInfo.profileFd.close();
18681                } catch (IOException e) {
18682                }
18683            }
18684        }
18685    }
18686
18687    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18689                userId, true, ALLOW_FULL_ONLY, callName, null);
18690        ProcessRecord proc = null;
18691        try {
18692            int pid = Integer.parseInt(process);
18693            synchronized (mPidsSelfLocked) {
18694                proc = mPidsSelfLocked.get(pid);
18695            }
18696        } catch (NumberFormatException e) {
18697        }
18698
18699        if (proc == null) {
18700            ArrayMap<String, SparseArray<ProcessRecord>> all
18701                    = mProcessNames.getMap();
18702            SparseArray<ProcessRecord> procs = all.get(process);
18703            if (procs != null && procs.size() > 0) {
18704                proc = procs.valueAt(0);
18705                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18706                    for (int i=1; i<procs.size(); i++) {
18707                        ProcessRecord thisProc = procs.valueAt(i);
18708                        if (thisProc.userId == userId) {
18709                            proc = thisProc;
18710                            break;
18711                        }
18712                    }
18713                }
18714            }
18715        }
18716
18717        return proc;
18718    }
18719
18720    public boolean dumpHeap(String process, int userId, boolean managed,
18721            String path, ParcelFileDescriptor fd) throws RemoteException {
18722
18723        try {
18724            synchronized (this) {
18725                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18726                // its own permission (same as profileControl).
18727                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18728                        != PackageManager.PERMISSION_GRANTED) {
18729                    throw new SecurityException("Requires permission "
18730                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18731                }
18732
18733                if (fd == null) {
18734                    throw new IllegalArgumentException("null fd");
18735                }
18736
18737                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18738                if (proc == null || proc.thread == null) {
18739                    throw new IllegalArgumentException("Unknown process: " + process);
18740                }
18741
18742                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18743                if (!isDebuggable) {
18744                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18745                        throw new SecurityException("Process not debuggable: " + proc);
18746                    }
18747                }
18748
18749                proc.thread.dumpHeap(managed, path, fd);
18750                fd = null;
18751                return true;
18752            }
18753        } catch (RemoteException e) {
18754            throw new IllegalStateException("Process disappeared");
18755        } finally {
18756            if (fd != null) {
18757                try {
18758                    fd.close();
18759                } catch (IOException e) {
18760                }
18761            }
18762        }
18763    }
18764
18765    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18766    public void monitor() {
18767        synchronized (this) { }
18768    }
18769
18770    void onCoreSettingsChange(Bundle settings) {
18771        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18772            ProcessRecord processRecord = mLruProcesses.get(i);
18773            try {
18774                if (processRecord.thread != null) {
18775                    processRecord.thread.setCoreSettings(settings);
18776                }
18777            } catch (RemoteException re) {
18778                /* ignore */
18779            }
18780        }
18781    }
18782
18783    // Multi-user methods
18784
18785    /**
18786     * Start user, if its not already running, but don't bring it to foreground.
18787     */
18788    @Override
18789    public boolean startUserInBackground(final int userId) {
18790        return startUser(userId, /* foreground */ false);
18791    }
18792
18793    /**
18794     * Start user, if its not already running, and bring it to foreground.
18795     */
18796    boolean startUserInForeground(final int userId, Dialog dlg) {
18797        boolean result = startUser(userId, /* foreground */ true);
18798        dlg.dismiss();
18799        return result;
18800    }
18801
18802    /**
18803     * Refreshes the list of users related to the current user when either a
18804     * user switch happens or when a new related user is started in the
18805     * background.
18806     */
18807    private void updateCurrentProfileIdsLocked() {
18808        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18809                mCurrentUserId, false /* enabledOnly */);
18810        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18811        for (int i = 0; i < currentProfileIds.length; i++) {
18812            currentProfileIds[i] = profiles.get(i).id;
18813        }
18814        mCurrentProfileIds = currentProfileIds;
18815
18816        synchronized (mUserProfileGroupIdsSelfLocked) {
18817            mUserProfileGroupIdsSelfLocked.clear();
18818            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18819            for (int i = 0; i < users.size(); i++) {
18820                UserInfo user = users.get(i);
18821                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18822                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18823                }
18824            }
18825        }
18826    }
18827
18828    private Set getProfileIdsLocked(int userId) {
18829        Set userIds = new HashSet<Integer>();
18830        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18831                userId, false /* enabledOnly */);
18832        for (UserInfo user : profiles) {
18833            userIds.add(Integer.valueOf(user.id));
18834        }
18835        return userIds;
18836    }
18837
18838    @Override
18839    public boolean switchUser(final int userId) {
18840        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18841        String userName;
18842        synchronized (this) {
18843            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18844            if (userInfo == null) {
18845                Slog.w(TAG, "No user info for user #" + userId);
18846                return false;
18847            }
18848            if (userInfo.isManagedProfile()) {
18849                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18850                return false;
18851            }
18852            userName = userInfo.name;
18853            mTargetUserId = userId;
18854        }
18855        mHandler.removeMessages(START_USER_SWITCH_MSG);
18856        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18857        return true;
18858    }
18859
18860    private void showUserSwitchDialog(int userId, String userName) {
18861        // The dialog will show and then initiate the user switch by calling startUserInForeground
18862        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18863                true /* above system */);
18864        d.show();
18865    }
18866
18867    private boolean startUser(final int userId, final boolean foreground) {
18868        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18869                != PackageManager.PERMISSION_GRANTED) {
18870            String msg = "Permission Denial: switchUser() from pid="
18871                    + Binder.getCallingPid()
18872                    + ", uid=" + Binder.getCallingUid()
18873                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18874            Slog.w(TAG, msg);
18875            throw new SecurityException(msg);
18876        }
18877
18878        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18879
18880        final long ident = Binder.clearCallingIdentity();
18881        try {
18882            synchronized (this) {
18883                final int oldUserId = mCurrentUserId;
18884                if (oldUserId == userId) {
18885                    return true;
18886                }
18887
18888                mStackSupervisor.setLockTaskModeLocked(null, false);
18889
18890                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18891                if (userInfo == null) {
18892                    Slog.w(TAG, "No user info for user #" + userId);
18893                    return false;
18894                }
18895                if (foreground && userInfo.isManagedProfile()) {
18896                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18897                    return false;
18898                }
18899
18900                if (foreground) {
18901                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18902                            R.anim.screen_user_enter);
18903                }
18904
18905                boolean needStart = false;
18906
18907                // If the user we are switching to is not currently started, then
18908                // we need to start it now.
18909                if (mStartedUsers.get(userId) == null) {
18910                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18911                    updateStartedUserArrayLocked();
18912                    needStart = true;
18913                }
18914
18915                final Integer userIdInt = Integer.valueOf(userId);
18916                mUserLru.remove(userIdInt);
18917                mUserLru.add(userIdInt);
18918
18919                if (foreground) {
18920                    mCurrentUserId = userId;
18921                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18922                    updateCurrentProfileIdsLocked();
18923                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18924                    // Once the internal notion of the active user has switched, we lock the device
18925                    // with the option to show the user switcher on the keyguard.
18926                    mWindowManager.lockNow(null);
18927                } else {
18928                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18929                    updateCurrentProfileIdsLocked();
18930                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18931                    mUserLru.remove(currentUserIdInt);
18932                    mUserLru.add(currentUserIdInt);
18933                }
18934
18935                final UserStartedState uss = mStartedUsers.get(userId);
18936
18937                // Make sure user is in the started state.  If it is currently
18938                // stopping, we need to knock that off.
18939                if (uss.mState == UserStartedState.STATE_STOPPING) {
18940                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18941                    // so we can just fairly silently bring the user back from
18942                    // the almost-dead.
18943                    uss.mState = UserStartedState.STATE_RUNNING;
18944                    updateStartedUserArrayLocked();
18945                    needStart = true;
18946                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18947                    // This means ACTION_SHUTDOWN has been sent, so we will
18948                    // need to treat this as a new boot of the user.
18949                    uss.mState = UserStartedState.STATE_BOOTING;
18950                    updateStartedUserArrayLocked();
18951                    needStart = true;
18952                }
18953
18954                if (uss.mState == UserStartedState.STATE_BOOTING) {
18955                    // Booting up a new user, need to tell system services about it.
18956                    // Note that this is on the same handler as scheduling of broadcasts,
18957                    // which is important because it needs to go first.
18958                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18959                }
18960
18961                if (foreground) {
18962                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18963                            oldUserId));
18964                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18965                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18966                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18967                            oldUserId, userId, uss));
18968                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18969                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18970                }
18971
18972                if (needStart) {
18973                    // Send USER_STARTED broadcast
18974                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18975                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18976                            | Intent.FLAG_RECEIVER_FOREGROUND);
18977                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18978                    broadcastIntentLocked(null, null, intent,
18979                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18980                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18981                }
18982
18983                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18984                    if (userId != UserHandle.USER_OWNER) {
18985                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18986                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18987                        broadcastIntentLocked(null, null, intent, null,
18988                                new IIntentReceiver.Stub() {
18989                                    public void performReceive(Intent intent, int resultCode,
18990                                            String data, Bundle extras, boolean ordered,
18991                                            boolean sticky, int sendingUser) {
18992                                        onUserInitialized(uss, foreground, oldUserId, userId);
18993                                    }
18994                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18995                                true, false, MY_PID, Process.SYSTEM_UID,
18996                                userId);
18997                        uss.initializing = true;
18998                    } else {
18999                        getUserManagerLocked().makeInitialized(userInfo.id);
19000                    }
19001                }
19002
19003                if (foreground) {
19004                    if (!uss.initializing) {
19005                        moveUserToForeground(uss, oldUserId, userId);
19006                    }
19007                } else {
19008                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19009                }
19010
19011                if (needStart) {
19012                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19013                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19014                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19015                    broadcastIntentLocked(null, null, intent,
19016                            null, new IIntentReceiver.Stub() {
19017                                @Override
19018                                public void performReceive(Intent intent, int resultCode, String data,
19019                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19020                                        throws RemoteException {
19021                                }
19022                            }, 0, null, null,
19023                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19024                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19025                }
19026            }
19027        } finally {
19028            Binder.restoreCallingIdentity(ident);
19029        }
19030
19031        return true;
19032    }
19033
19034    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19035        long ident = Binder.clearCallingIdentity();
19036        try {
19037            Intent intent;
19038            if (oldUserId >= 0) {
19039                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19040                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19041                int count = profiles.size();
19042                for (int i = 0; i < count; i++) {
19043                    int profileUserId = profiles.get(i).id;
19044                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19045                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19046                            | Intent.FLAG_RECEIVER_FOREGROUND);
19047                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19048                    broadcastIntentLocked(null, null, intent,
19049                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19050                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19051                }
19052            }
19053            if (newUserId >= 0) {
19054                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19055                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19056                int count = profiles.size();
19057                for (int i = 0; i < count; i++) {
19058                    int profileUserId = profiles.get(i).id;
19059                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19060                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19061                            | Intent.FLAG_RECEIVER_FOREGROUND);
19062                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19063                    broadcastIntentLocked(null, null, intent,
19064                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19065                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19066                }
19067                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19068                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19069                        | Intent.FLAG_RECEIVER_FOREGROUND);
19070                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19071                broadcastIntentLocked(null, null, intent,
19072                        null, null, 0, null, null,
19073                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19074                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19075            }
19076        } finally {
19077            Binder.restoreCallingIdentity(ident);
19078        }
19079    }
19080
19081    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19082            final int newUserId) {
19083        final int N = mUserSwitchObservers.beginBroadcast();
19084        if (N > 0) {
19085            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19086                int mCount = 0;
19087                @Override
19088                public void sendResult(Bundle data) throws RemoteException {
19089                    synchronized (ActivityManagerService.this) {
19090                        if (mCurUserSwitchCallback == this) {
19091                            mCount++;
19092                            if (mCount == N) {
19093                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19094                            }
19095                        }
19096                    }
19097                }
19098            };
19099            synchronized (this) {
19100                uss.switching = true;
19101                mCurUserSwitchCallback = callback;
19102            }
19103            for (int i=0; i<N; i++) {
19104                try {
19105                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19106                            newUserId, callback);
19107                } catch (RemoteException e) {
19108                }
19109            }
19110        } else {
19111            synchronized (this) {
19112                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19113            }
19114        }
19115        mUserSwitchObservers.finishBroadcast();
19116    }
19117
19118    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19119        synchronized (this) {
19120            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19121            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19122        }
19123    }
19124
19125    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19126        mCurUserSwitchCallback = null;
19127        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19128        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19129                oldUserId, newUserId, uss));
19130    }
19131
19132    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19133        synchronized (this) {
19134            if (foreground) {
19135                moveUserToForeground(uss, oldUserId, newUserId);
19136            }
19137        }
19138
19139        completeSwitchAndInitalize(uss, newUserId, true, false);
19140    }
19141
19142    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19143        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19144        if (homeInFront) {
19145            startHomeActivityLocked(newUserId);
19146        } else {
19147            mStackSupervisor.resumeTopActivitiesLocked();
19148        }
19149        EventLogTags.writeAmSwitchUser(newUserId);
19150        getUserManagerLocked().userForeground(newUserId);
19151        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19152    }
19153
19154    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19155        completeSwitchAndInitalize(uss, newUserId, false, true);
19156    }
19157
19158    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19159            boolean clearInitializing, boolean clearSwitching) {
19160        boolean unfrozen = false;
19161        synchronized (this) {
19162            if (clearInitializing) {
19163                uss.initializing = false;
19164                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19165            }
19166            if (clearSwitching) {
19167                uss.switching = false;
19168            }
19169            if (!uss.switching && !uss.initializing) {
19170                mWindowManager.stopFreezingScreen();
19171                unfrozen = true;
19172            }
19173        }
19174        if (unfrozen) {
19175            final int N = mUserSwitchObservers.beginBroadcast();
19176            for (int i=0; i<N; i++) {
19177                try {
19178                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19179                } catch (RemoteException e) {
19180                }
19181            }
19182            mUserSwitchObservers.finishBroadcast();
19183        }
19184        stopGuestUserIfBackground();
19185    }
19186
19187    /**
19188     * Stops the guest user if it has gone to the background.
19189     */
19190    private void stopGuestUserIfBackground() {
19191        synchronized (this) {
19192            final int num = mUserLru.size();
19193            for (int i = 0; i < num; i++) {
19194                Integer oldUserId = mUserLru.get(i);
19195                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19196                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19197                        || oldUss.mState == UserStartedState.STATE_STOPPING
19198                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19199                    continue;
19200                }
19201                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19202                if (userInfo.isGuest()) {
19203                    // This is a user to be stopped.
19204                    stopUserLocked(oldUserId, null);
19205                    break;
19206                }
19207            }
19208        }
19209    }
19210
19211    void scheduleStartProfilesLocked() {
19212        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19213            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19214                    DateUtils.SECOND_IN_MILLIS);
19215        }
19216    }
19217
19218    void startProfilesLocked() {
19219        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19220        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19221                mCurrentUserId, false /* enabledOnly */);
19222        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19223        for (UserInfo user : profiles) {
19224            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19225                    && user.id != mCurrentUserId) {
19226                toStart.add(user);
19227            }
19228        }
19229        final int n = toStart.size();
19230        int i = 0;
19231        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19232            startUserInBackground(toStart.get(i).id);
19233        }
19234        if (i < n) {
19235            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19236        }
19237    }
19238
19239    void finishUserBoot(UserStartedState uss) {
19240        synchronized (this) {
19241            if (uss.mState == UserStartedState.STATE_BOOTING
19242                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19243                uss.mState = UserStartedState.STATE_RUNNING;
19244                final int userId = uss.mHandle.getIdentifier();
19245                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19246                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19247                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19248                broadcastIntentLocked(null, null, intent,
19249                        null, null, 0, null, null,
19250                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19251                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19252            }
19253        }
19254    }
19255
19256    void finishUserSwitch(UserStartedState uss) {
19257        synchronized (this) {
19258            finishUserBoot(uss);
19259
19260            startProfilesLocked();
19261
19262            int num = mUserLru.size();
19263            int i = 0;
19264            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19265                Integer oldUserId = mUserLru.get(i);
19266                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19267                if (oldUss == null) {
19268                    // Shouldn't happen, but be sane if it does.
19269                    mUserLru.remove(i);
19270                    num--;
19271                    continue;
19272                }
19273                if (oldUss.mState == UserStartedState.STATE_STOPPING
19274                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19275                    // This user is already stopping, doesn't count.
19276                    num--;
19277                    i++;
19278                    continue;
19279                }
19280                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19281                    // Owner and current can't be stopped, but count as running.
19282                    i++;
19283                    continue;
19284                }
19285                // This is a user to be stopped.
19286                stopUserLocked(oldUserId, null);
19287                num--;
19288                i++;
19289            }
19290        }
19291    }
19292
19293    @Override
19294    public int stopUser(final int userId, final IStopUserCallback callback) {
19295        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19296                != PackageManager.PERMISSION_GRANTED) {
19297            String msg = "Permission Denial: switchUser() from pid="
19298                    + Binder.getCallingPid()
19299                    + ", uid=" + Binder.getCallingUid()
19300                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19301            Slog.w(TAG, msg);
19302            throw new SecurityException(msg);
19303        }
19304        if (userId <= 0) {
19305            throw new IllegalArgumentException("Can't stop primary user " + userId);
19306        }
19307        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19308        synchronized (this) {
19309            return stopUserLocked(userId, callback);
19310        }
19311    }
19312
19313    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19314        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19315        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19316            return ActivityManager.USER_OP_IS_CURRENT;
19317        }
19318
19319        final UserStartedState uss = mStartedUsers.get(userId);
19320        if (uss == null) {
19321            // User is not started, nothing to do...  but we do need to
19322            // callback if requested.
19323            if (callback != null) {
19324                mHandler.post(new Runnable() {
19325                    @Override
19326                    public void run() {
19327                        try {
19328                            callback.userStopped(userId);
19329                        } catch (RemoteException e) {
19330                        }
19331                    }
19332                });
19333            }
19334            return ActivityManager.USER_OP_SUCCESS;
19335        }
19336
19337        if (callback != null) {
19338            uss.mStopCallbacks.add(callback);
19339        }
19340
19341        if (uss.mState != UserStartedState.STATE_STOPPING
19342                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19343            uss.mState = UserStartedState.STATE_STOPPING;
19344            updateStartedUserArrayLocked();
19345
19346            long ident = Binder.clearCallingIdentity();
19347            try {
19348                // We are going to broadcast ACTION_USER_STOPPING and then
19349                // once that is done send a final ACTION_SHUTDOWN and then
19350                // stop the user.
19351                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19352                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19353                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19354                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19355                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19356                // This is the result receiver for the final shutdown broadcast.
19357                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19358                    @Override
19359                    public void performReceive(Intent intent, int resultCode, String data,
19360                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19361                        finishUserStop(uss);
19362                    }
19363                };
19364                // This is the result receiver for the initial stopping broadcast.
19365                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19366                    @Override
19367                    public void performReceive(Intent intent, int resultCode, String data,
19368                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19369                        // On to the next.
19370                        synchronized (ActivityManagerService.this) {
19371                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19372                                // Whoops, we are being started back up.  Abort, abort!
19373                                return;
19374                            }
19375                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19376                        }
19377                        mBatteryStatsService.noteEvent(
19378                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19379                                Integer.toString(userId), userId);
19380                        mSystemServiceManager.stopUser(userId);
19381                        broadcastIntentLocked(null, null, shutdownIntent,
19382                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19383                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19384                    }
19385                };
19386                // Kick things off.
19387                broadcastIntentLocked(null, null, stoppingIntent,
19388                        null, stoppingReceiver, 0, null, null,
19389                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19390                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19391            } finally {
19392                Binder.restoreCallingIdentity(ident);
19393            }
19394        }
19395
19396        return ActivityManager.USER_OP_SUCCESS;
19397    }
19398
19399    void finishUserStop(UserStartedState uss) {
19400        final int userId = uss.mHandle.getIdentifier();
19401        boolean stopped;
19402        ArrayList<IStopUserCallback> callbacks;
19403        synchronized (this) {
19404            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19405            if (mStartedUsers.get(userId) != uss) {
19406                stopped = false;
19407            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19408                stopped = false;
19409            } else {
19410                stopped = true;
19411                // User can no longer run.
19412                mStartedUsers.remove(userId);
19413                mUserLru.remove(Integer.valueOf(userId));
19414                updateStartedUserArrayLocked();
19415
19416                // Clean up all state and processes associated with the user.
19417                // Kill all the processes for the user.
19418                forceStopUserLocked(userId, "finish user");
19419            }
19420
19421            // Explicitly remove the old information in mRecentTasks.
19422            removeRecentTasksForUserLocked(userId);
19423        }
19424
19425        for (int i=0; i<callbacks.size(); i++) {
19426            try {
19427                if (stopped) callbacks.get(i).userStopped(userId);
19428                else callbacks.get(i).userStopAborted(userId);
19429            } catch (RemoteException e) {
19430            }
19431        }
19432
19433        if (stopped) {
19434            mSystemServiceManager.cleanupUser(userId);
19435            synchronized (this) {
19436                mStackSupervisor.removeUserLocked(userId);
19437            }
19438        }
19439    }
19440
19441    @Override
19442    public UserInfo getCurrentUser() {
19443        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19444                != PackageManager.PERMISSION_GRANTED) && (
19445                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19446                != PackageManager.PERMISSION_GRANTED)) {
19447            String msg = "Permission Denial: getCurrentUser() from pid="
19448                    + Binder.getCallingPid()
19449                    + ", uid=" + Binder.getCallingUid()
19450                    + " requires " + INTERACT_ACROSS_USERS;
19451            Slog.w(TAG, msg);
19452            throw new SecurityException(msg);
19453        }
19454        synchronized (this) {
19455            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19456            return getUserManagerLocked().getUserInfo(userId);
19457        }
19458    }
19459
19460    int getCurrentUserIdLocked() {
19461        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19462    }
19463
19464    @Override
19465    public boolean isUserRunning(int userId, boolean orStopped) {
19466        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19467                != PackageManager.PERMISSION_GRANTED) {
19468            String msg = "Permission Denial: isUserRunning() from pid="
19469                    + Binder.getCallingPid()
19470                    + ", uid=" + Binder.getCallingUid()
19471                    + " requires " + INTERACT_ACROSS_USERS;
19472            Slog.w(TAG, msg);
19473            throw new SecurityException(msg);
19474        }
19475        synchronized (this) {
19476            return isUserRunningLocked(userId, orStopped);
19477        }
19478    }
19479
19480    boolean isUserRunningLocked(int userId, boolean orStopped) {
19481        UserStartedState state = mStartedUsers.get(userId);
19482        if (state == null) {
19483            return false;
19484        }
19485        if (orStopped) {
19486            return true;
19487        }
19488        return state.mState != UserStartedState.STATE_STOPPING
19489                && state.mState != UserStartedState.STATE_SHUTDOWN;
19490    }
19491
19492    @Override
19493    public int[] getRunningUserIds() {
19494        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19495                != PackageManager.PERMISSION_GRANTED) {
19496            String msg = "Permission Denial: isUserRunning() from pid="
19497                    + Binder.getCallingPid()
19498                    + ", uid=" + Binder.getCallingUid()
19499                    + " requires " + INTERACT_ACROSS_USERS;
19500            Slog.w(TAG, msg);
19501            throw new SecurityException(msg);
19502        }
19503        synchronized (this) {
19504            return mStartedUserArray;
19505        }
19506    }
19507
19508    private void updateStartedUserArrayLocked() {
19509        int num = 0;
19510        for (int i=0; i<mStartedUsers.size();  i++) {
19511            UserStartedState uss = mStartedUsers.valueAt(i);
19512            // This list does not include stopping users.
19513            if (uss.mState != UserStartedState.STATE_STOPPING
19514                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19515                num++;
19516            }
19517        }
19518        mStartedUserArray = new int[num];
19519        num = 0;
19520        for (int i=0; i<mStartedUsers.size();  i++) {
19521            UserStartedState uss = mStartedUsers.valueAt(i);
19522            if (uss.mState != UserStartedState.STATE_STOPPING
19523                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19524                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19525                num++;
19526            }
19527        }
19528    }
19529
19530    @Override
19531    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19532        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19533                != PackageManager.PERMISSION_GRANTED) {
19534            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19535                    + Binder.getCallingPid()
19536                    + ", uid=" + Binder.getCallingUid()
19537                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19538            Slog.w(TAG, msg);
19539            throw new SecurityException(msg);
19540        }
19541
19542        mUserSwitchObservers.register(observer);
19543    }
19544
19545    @Override
19546    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19547        mUserSwitchObservers.unregister(observer);
19548    }
19549
19550    private boolean userExists(int userId) {
19551        if (userId == 0) {
19552            return true;
19553        }
19554        UserManagerService ums = getUserManagerLocked();
19555        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19556    }
19557
19558    int[] getUsersLocked() {
19559        UserManagerService ums = getUserManagerLocked();
19560        return ums != null ? ums.getUserIds() : new int[] { 0 };
19561    }
19562
19563    UserManagerService getUserManagerLocked() {
19564        if (mUserManager == null) {
19565            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19566            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19567        }
19568        return mUserManager;
19569    }
19570
19571    private int applyUserId(int uid, int userId) {
19572        return UserHandle.getUid(userId, uid);
19573    }
19574
19575    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19576        if (info == null) return null;
19577        ApplicationInfo newInfo = new ApplicationInfo(info);
19578        newInfo.uid = applyUserId(info.uid, userId);
19579        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19580                + info.packageName;
19581        return newInfo;
19582    }
19583
19584    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19585        if (aInfo == null
19586                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19587            return aInfo;
19588        }
19589
19590        ActivityInfo info = new ActivityInfo(aInfo);
19591        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19592        return info;
19593    }
19594
19595    private final class LocalService extends ActivityManagerInternal {
19596        @Override
19597        public void onWakefulnessChanged(int wakefulness) {
19598            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19599        }
19600
19601        @Override
19602        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19603                String processName, String abiOverride, int uid, Runnable crashHandler) {
19604            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19605                    processName, abiOverride, uid, crashHandler);
19606        }
19607    }
19608
19609    /**
19610     * An implementation of IAppTask, that allows an app to manage its own tasks via
19611     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19612     * only the process that calls getAppTasks() can call the AppTask methods.
19613     */
19614    class AppTaskImpl extends IAppTask.Stub {
19615        private int mTaskId;
19616        private int mCallingUid;
19617
19618        public AppTaskImpl(int taskId, int callingUid) {
19619            mTaskId = taskId;
19620            mCallingUid = callingUid;
19621        }
19622
19623        private void checkCaller() {
19624            if (mCallingUid != Binder.getCallingUid()) {
19625                throw new SecurityException("Caller " + mCallingUid
19626                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19627            }
19628        }
19629
19630        @Override
19631        public void finishAndRemoveTask() {
19632            checkCaller();
19633
19634            synchronized (ActivityManagerService.this) {
19635                long origId = Binder.clearCallingIdentity();
19636                try {
19637                    if (!removeTaskByIdLocked(mTaskId, false)) {
19638                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19639                    }
19640                } finally {
19641                    Binder.restoreCallingIdentity(origId);
19642                }
19643            }
19644        }
19645
19646        @Override
19647        public ActivityManager.RecentTaskInfo getTaskInfo() {
19648            checkCaller();
19649
19650            synchronized (ActivityManagerService.this) {
19651                long origId = Binder.clearCallingIdentity();
19652                try {
19653                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19654                    if (tr == null) {
19655                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19656                    }
19657                    return createRecentTaskInfoFromTaskRecord(tr);
19658                } finally {
19659                    Binder.restoreCallingIdentity(origId);
19660                }
19661            }
19662        }
19663
19664        @Override
19665        public void moveToFront() {
19666            checkCaller();
19667            // Will bring task to front if it already has a root activity.
19668            startActivityFromRecentsInner(mTaskId, null);
19669        }
19670
19671        @Override
19672        public int startActivity(IBinder whoThread, String callingPackage,
19673                Intent intent, String resolvedType, Bundle options) {
19674            checkCaller();
19675
19676            int callingUser = UserHandle.getCallingUserId();
19677            TaskRecord tr;
19678            IApplicationThread appThread;
19679            synchronized (ActivityManagerService.this) {
19680                tr = recentTaskForIdLocked(mTaskId);
19681                if (tr == null) {
19682                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19683                }
19684                appThread = ApplicationThreadNative.asInterface(whoThread);
19685                if (appThread == null) {
19686                    throw new IllegalArgumentException("Bad app thread " + appThread);
19687                }
19688            }
19689            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19690                    resolvedType, null, null, null, null, 0, 0, null, null,
19691                    null, options, callingUser, null, tr);
19692        }
19693
19694        @Override
19695        public void setExcludeFromRecents(boolean exclude) {
19696            checkCaller();
19697
19698            synchronized (ActivityManagerService.this) {
19699                long origId = Binder.clearCallingIdentity();
19700                try {
19701                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19702                    if (tr == null) {
19703                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19704                    }
19705                    Intent intent = tr.getBaseIntent();
19706                    if (exclude) {
19707                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19708                    } else {
19709                        intent.setFlags(intent.getFlags()
19710                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19711                    }
19712                } finally {
19713                    Binder.restoreCallingIdentity(origId);
19714                }
19715            }
19716        }
19717    }
19718}
19719