ActivityManagerService.java revision ae6cc8af2674909924fb18cb73763a110bee63dd
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    /**
753     * Backup/restore process management
754     */
755    String mBackupAppName = null;
756    BackupRecord mBackupTarget = null;
757
758    final ProviderMap mProviderMap;
759
760    /**
761     * List of content providers who have clients waiting for them.  The
762     * application is currently being launched and the provider will be
763     * removed from this list once it is published.
764     */
765    final ArrayList<ContentProviderRecord> mLaunchingProviders
766            = new ArrayList<ContentProviderRecord>();
767
768    /**
769     * File storing persisted {@link #mGrantedUriPermissions}.
770     */
771    private final AtomicFile mGrantFile;
772
773    /** XML constants used in {@link #mGrantFile} */
774    private static final String TAG_URI_GRANTS = "uri-grants";
775    private static final String TAG_URI_GRANT = "uri-grant";
776    private static final String ATTR_USER_HANDLE = "userHandle";
777    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
778    private static final String ATTR_TARGET_USER_ID = "targetUserId";
779    private static final String ATTR_SOURCE_PKG = "sourcePkg";
780    private static final String ATTR_TARGET_PKG = "targetPkg";
781    private static final String ATTR_URI = "uri";
782    private static final String ATTR_MODE_FLAGS = "modeFlags";
783    private static final String ATTR_CREATED_TIME = "createdTime";
784    private static final String ATTR_PREFIX = "prefix";
785
786    /**
787     * Global set of specific {@link Uri} permissions that have been granted.
788     * This optimized lookup structure maps from {@link UriPermission#targetUid}
789     * to {@link UriPermission#uri} to {@link UriPermission}.
790     */
791    @GuardedBy("this")
792    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
793            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
794
795    public static class GrantUri {
796        public final int sourceUserId;
797        public final Uri uri;
798        public boolean prefix;
799
800        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
801            this.sourceUserId = sourceUserId;
802            this.uri = uri;
803            this.prefix = prefix;
804        }
805
806        @Override
807        public int hashCode() {
808            int hashCode = 1;
809            hashCode = 31 * hashCode + sourceUserId;
810            hashCode = 31 * hashCode + uri.hashCode();
811            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
812            return hashCode;
813        }
814
815        @Override
816        public boolean equals(Object o) {
817            if (o instanceof GrantUri) {
818                GrantUri other = (GrantUri) o;
819                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
820                        && prefix == other.prefix;
821            }
822            return false;
823        }
824
825        @Override
826        public String toString() {
827            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
828            if (prefix) result += " [prefix]";
829            return result;
830        }
831
832        public String toSafeString() {
833            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
834            if (prefix) result += " [prefix]";
835            return result;
836        }
837
838        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
839            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
840                    ContentProvider.getUriWithoutUserId(uri), false);
841        }
842    }
843
844    CoreSettingsObserver mCoreSettingsObserver;
845
846    /**
847     * Thread-local storage used to carry caller permissions over through
848     * indirect content-provider access.
849     */
850    private class Identity {
851        public final IBinder token;
852        public final int pid;
853        public final int uid;
854
855        Identity(IBinder _token, int _pid, int _uid) {
856            token = _token;
857            pid = _pid;
858            uid = _uid;
859        }
860    }
861
862    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
863
864    /**
865     * All information we have collected about the runtime performance of
866     * any user id that can impact battery performance.
867     */
868    final BatteryStatsService mBatteryStatsService;
869
870    /**
871     * Information about component usage
872     */
873    UsageStatsManagerInternal mUsageStatsService;
874
875    /**
876     * Information about and control over application operations
877     */
878    final AppOpsService mAppOpsService;
879
880    /**
881     * Save recent tasks information across reboots.
882     */
883    final TaskPersister mTaskPersister;
884
885    /**
886     * Current configuration information.  HistoryRecord objects are given
887     * a reference to this object to indicate which configuration they are
888     * currently running in, so this object must be kept immutable.
889     */
890    Configuration mConfiguration = new Configuration();
891
892    /**
893     * Current sequencing integer of the configuration, for skipping old
894     * configurations.
895     */
896    int mConfigurationSeq = 0;
897
898    /**
899     * Hardware-reported OpenGLES version.
900     */
901    final int GL_ES_VERSION;
902
903    /**
904     * List of initialization arguments to pass to all processes when binding applications to them.
905     * For example, references to the commonly used services.
906     */
907    HashMap<String, IBinder> mAppBindArgs;
908
909    /**
910     * Temporary to avoid allocations.  Protected by main lock.
911     */
912    final StringBuilder mStringBuilder = new StringBuilder(256);
913
914    /**
915     * Used to control how we initialize the service.
916     */
917    ComponentName mTopComponent;
918    String mTopAction = Intent.ACTION_MAIN;
919    String mTopData;
920    boolean mProcessesReady = false;
921    boolean mSystemReady = false;
922    boolean mBooting = false;
923    boolean mCallFinishBooting = false;
924    boolean mBootAnimationComplete = false;
925    boolean mWaitingUpdate = false;
926    boolean mDidUpdate = false;
927    boolean mOnBattery = false;
928    boolean mLaunchWarningShown = false;
929
930    Context mContext;
931
932    int mFactoryTest;
933
934    boolean mCheckedForSetup;
935
936    /**
937     * The time at which we will allow normal application switches again,
938     * after a call to {@link #stopAppSwitches()}.
939     */
940    long mAppSwitchesAllowedTime;
941
942    /**
943     * This is set to true after the first switch after mAppSwitchesAllowedTime
944     * is set; any switches after that will clear the time.
945     */
946    boolean mDidAppSwitch;
947
948    /**
949     * Last time (in realtime) at which we checked for power usage.
950     */
951    long mLastPowerCheckRealtime;
952
953    /**
954     * Last time (in uptime) at which we checked for power usage.
955     */
956    long mLastPowerCheckUptime;
957
958    /**
959     * Set while we are wanting to sleep, to prevent any
960     * activities from being started/resumed.
961     */
962    private boolean mSleeping = false;
963
964    /**
965     * Set while we are running a voice interaction.  This overrides
966     * sleeping while it is active.
967     */
968    private boolean mRunningVoice = false;
969
970    /**
971     * State of external calls telling us if the device is awake or asleep.
972     */
973    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
974
975    static final int LOCK_SCREEN_HIDDEN = 0;
976    static final int LOCK_SCREEN_LEAVING = 1;
977    static final int LOCK_SCREEN_SHOWN = 2;
978    /**
979     * State of external call telling us if the lock screen is shown.
980     */
981    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
982
983    /**
984     * Set if we are shutting down the system, similar to sleeping.
985     */
986    boolean mShuttingDown = false;
987
988    /**
989     * Current sequence id for oom_adj computation traversal.
990     */
991    int mAdjSeq = 0;
992
993    /**
994     * Current sequence id for process LRU updating.
995     */
996    int mLruSeq = 0;
997
998    /**
999     * Keep track of the non-cached/empty process we last found, to help
1000     * determine how to distribute cached/empty processes next time.
1001     */
1002    int mNumNonCachedProcs = 0;
1003
1004    /**
1005     * Keep track of the number of cached hidden procs, to balance oom adj
1006     * distribution between those and empty procs.
1007     */
1008    int mNumCachedHiddenProcs = 0;
1009
1010    /**
1011     * Keep track of the number of service processes we last found, to
1012     * determine on the next iteration which should be B services.
1013     */
1014    int mNumServiceProcs = 0;
1015    int mNewNumAServiceProcs = 0;
1016    int mNewNumServiceProcs = 0;
1017
1018    /**
1019     * Allow the current computed overall memory level of the system to go down?
1020     * This is set to false when we are killing processes for reasons other than
1021     * memory management, so that the now smaller process list will not be taken as
1022     * an indication that memory is tighter.
1023     */
1024    boolean mAllowLowerMemLevel = false;
1025
1026    /**
1027     * The last computed memory level, for holding when we are in a state that
1028     * processes are going away for other reasons.
1029     */
1030    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1031
1032    /**
1033     * The last total number of process we have, to determine if changes actually look
1034     * like a shrinking number of process due to lower RAM.
1035     */
1036    int mLastNumProcesses;
1037
1038    /**
1039     * The uptime of the last time we performed idle maintenance.
1040     */
1041    long mLastIdleTime = SystemClock.uptimeMillis();
1042
1043    /**
1044     * Total time spent with RAM that has been added in the past since the last idle time.
1045     */
1046    long mLowRamTimeSinceLastIdle = 0;
1047
1048    /**
1049     * If RAM is currently low, when that horrible situation started.
1050     */
1051    long mLowRamStartTime = 0;
1052
1053    /**
1054     * For reporting to battery stats the current top application.
1055     */
1056    private String mCurResumedPackage = null;
1057    private int mCurResumedUid = -1;
1058
1059    /**
1060     * For reporting to battery stats the apps currently running foreground
1061     * service.  The ProcessMap is package/uid tuples; each of these contain
1062     * an array of the currently foreground processes.
1063     */
1064    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1065            = new ProcessMap<ArrayList<ProcessRecord>>();
1066
1067    /**
1068     * This is set if we had to do a delayed dexopt of an app before launching
1069     * it, to increase the ANR timeouts in that case.
1070     */
1071    boolean mDidDexOpt;
1072
1073    /**
1074     * Set if the systemServer made a call to enterSafeMode.
1075     */
1076    boolean mSafeMode;
1077
1078    /**
1079     * If true, we are running under a test environment so will sample PSS from processes
1080     * much more rapidly to try to collect better data when the tests are rapidly
1081     * running through apps.
1082     */
1083    boolean mTestPssMode = false;
1084
1085    String mDebugApp = null;
1086    boolean mWaitForDebugger = false;
1087    boolean mDebugTransient = false;
1088    String mOrigDebugApp = null;
1089    boolean mOrigWaitForDebugger = false;
1090    boolean mAlwaysFinishActivities = false;
1091    IActivityController mController = null;
1092    String mProfileApp = null;
1093    ProcessRecord mProfileProc = null;
1094    String mProfileFile;
1095    ParcelFileDescriptor mProfileFd;
1096    int mSamplingInterval = 0;
1097    boolean mAutoStopProfiler = false;
1098    int mProfileType = 0;
1099    String mOpenGlTraceApp = null;
1100
1101    final long[] mTmpLong = new long[1];
1102
1103    static class ProcessChangeItem {
1104        static final int CHANGE_ACTIVITIES = 1<<0;
1105        static final int CHANGE_PROCESS_STATE = 1<<1;
1106        int changes;
1107        int uid;
1108        int pid;
1109        int processState;
1110        boolean foregroundActivities;
1111    }
1112
1113    final RemoteCallbackList<IProcessObserver> mProcessObservers
1114            = new RemoteCallbackList<IProcessObserver>();
1115    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1116
1117    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1118            = new ArrayList<ProcessChangeItem>();
1119    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1120            = new ArrayList<ProcessChangeItem>();
1121
1122    /**
1123     * Runtime CPU use collection thread.  This object's lock is used to
1124     * perform synchronization with the thread (notifying it to run).
1125     */
1126    final Thread mProcessCpuThread;
1127
1128    /**
1129     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1130     * Must acquire this object's lock when accessing it.
1131     * NOTE: this lock will be held while doing long operations (trawling
1132     * through all processes in /proc), so it should never be acquired by
1133     * any critical paths such as when holding the main activity manager lock.
1134     */
1135    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1136            MONITOR_THREAD_CPU_USAGE);
1137    final AtomicLong mLastCpuTime = new AtomicLong(0);
1138    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1139
1140    long mLastWriteTime = 0;
1141
1142    /**
1143     * Used to retain an update lock when the foreground activity is in
1144     * immersive mode.
1145     */
1146    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1147
1148    /**
1149     * Set to true after the system has finished booting.
1150     */
1151    boolean mBooted = false;
1152
1153    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1154    int mProcessLimitOverride = -1;
1155
1156    WindowManagerService mWindowManager;
1157
1158    final ActivityThread mSystemThread;
1159
1160    // Holds the current foreground user's id
1161    int mCurrentUserId = 0;
1162    // Holds the target user's id during a user switch
1163    int mTargetUserId = UserHandle.USER_NULL;
1164    // If there are multiple profiles for the current user, their ids are here
1165    // Currently only the primary user can have managed profiles
1166    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1167
1168    /**
1169     * Mapping from each known user ID to the profile group ID it is associated with.
1170     */
1171    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1172
1173    private UserManagerService mUserManager;
1174
1175    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1176        final ProcessRecord mApp;
1177        final int mPid;
1178        final IApplicationThread mAppThread;
1179
1180        AppDeathRecipient(ProcessRecord app, int pid,
1181                IApplicationThread thread) {
1182            if (localLOGV) Slog.v(
1183                TAG, "New death recipient " + this
1184                + " for thread " + thread.asBinder());
1185            mApp = app;
1186            mPid = pid;
1187            mAppThread = thread;
1188        }
1189
1190        @Override
1191        public void binderDied() {
1192            if (localLOGV) Slog.v(
1193                TAG, "Death received in " + this
1194                + " for thread " + mAppThread.asBinder());
1195            synchronized(ActivityManagerService.this) {
1196                appDiedLocked(mApp, mPid, mAppThread);
1197            }
1198        }
1199    }
1200
1201    static final int SHOW_ERROR_MSG = 1;
1202    static final int SHOW_NOT_RESPONDING_MSG = 2;
1203    static final int SHOW_FACTORY_ERROR_MSG = 3;
1204    static final int UPDATE_CONFIGURATION_MSG = 4;
1205    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1206    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1207    static final int SERVICE_TIMEOUT_MSG = 12;
1208    static final int UPDATE_TIME_ZONE = 13;
1209    static final int SHOW_UID_ERROR_MSG = 14;
1210    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1211    static final int PROC_START_TIMEOUT_MSG = 20;
1212    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1213    static final int KILL_APPLICATION_MSG = 22;
1214    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1215    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1216    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1217    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1218    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1219    static final int CLEAR_DNS_CACHE_MSG = 28;
1220    static final int UPDATE_HTTP_PROXY_MSG = 29;
1221    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1222    static final int DISPATCH_PROCESSES_CHANGED = 31;
1223    static final int DISPATCH_PROCESS_DIED = 32;
1224    static final int REPORT_MEM_USAGE_MSG = 33;
1225    static final int REPORT_USER_SWITCH_MSG = 34;
1226    static final int CONTINUE_USER_SWITCH_MSG = 35;
1227    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1228    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1229    static final int PERSIST_URI_GRANTS_MSG = 38;
1230    static final int REQUEST_ALL_PSS_MSG = 39;
1231    static final int START_PROFILES_MSG = 40;
1232    static final int UPDATE_TIME = 41;
1233    static final int SYSTEM_USER_START_MSG = 42;
1234    static final int SYSTEM_USER_CURRENT_MSG = 43;
1235    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1236    static final int FINISH_BOOTING_MSG = 45;
1237    static final int START_USER_SWITCH_MSG = 46;
1238    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1239    static final int DISMISS_DIALOG_MSG = 48;
1240    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1241
1242    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1243    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1244    static final int FIRST_COMPAT_MODE_MSG = 300;
1245    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1246
1247    CompatModeDialog mCompatModeDialog;
1248    long mLastMemUsageReportTime = 0;
1249
1250    /**
1251     * Flag whether the current user is a "monkey", i.e. whether
1252     * the UI is driven by a UI automation tool.
1253     */
1254    private boolean mUserIsMonkey;
1255
1256    /** Flag whether the device has a Recents UI */
1257    boolean mHasRecents;
1258
1259    /** The dimensions of the thumbnails in the Recents UI. */
1260    int mThumbnailWidth;
1261    int mThumbnailHeight;
1262
1263    final ServiceThread mHandlerThread;
1264    final MainHandler mHandler;
1265
1266    final class MainHandler extends Handler {
1267        public MainHandler(Looper looper) {
1268            super(looper, null, true);
1269        }
1270
1271        @Override
1272        public void handleMessage(Message msg) {
1273            switch (msg.what) {
1274            case SHOW_ERROR_MSG: {
1275                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1277                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1278                synchronized (ActivityManagerService.this) {
1279                    ProcessRecord proc = (ProcessRecord)data.get("app");
1280                    AppErrorResult res = (AppErrorResult) data.get("result");
1281                    if (proc != null && proc.crashDialog != null) {
1282                        Slog.e(TAG, "App already has crash dialog: " + proc);
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                        return;
1287                    }
1288                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1289                            >= Process.FIRST_APPLICATION_UID
1290                            && proc.pid != MY_PID);
1291                    for (int userId : mCurrentProfileIds) {
1292                        isBackground &= (proc.userId != userId);
1293                    }
1294                    if (isBackground && !showBackground) {
1295                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1296                        if (res != null) {
1297                            res.set(0);
1298                        }
1299                        return;
1300                    }
1301                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1302                        Dialog d = new AppErrorDialog(mContext,
1303                                ActivityManagerService.this, res, proc);
1304                        d.show();
1305                        proc.crashDialog = d;
1306                    } else {
1307                        // The device is asleep, so just pretend that the user
1308                        // saw a crash dialog and hit "force quit".
1309                        if (res != null) {
1310                            res.set(0);
1311                        }
1312                    }
1313                }
1314
1315                ensureBootCompleted();
1316            } break;
1317            case SHOW_NOT_RESPONDING_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                    ProcessRecord proc = (ProcessRecord)data.get("app");
1321                    if (proc != null && proc.anrDialog != null) {
1322                        Slog.e(TAG, "App already has anr dialog: " + proc);
1323                        return;
1324                    }
1325
1326                    Intent intent = new Intent("android.intent.action.ANR");
1327                    if (!mProcessesReady) {
1328                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1329                                | Intent.FLAG_RECEIVER_FOREGROUND);
1330                    }
1331                    broadcastIntentLocked(null, null, intent,
1332                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1333                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1334
1335                    if (mShowDialogs) {
1336                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1337                                mContext, proc, (ActivityRecord)data.get("activity"),
1338                                msg.arg1 != 0);
1339                        d.show();
1340                        proc.anrDialog = d;
1341                    } else {
1342                        // Just kill the app if there is no dialog to be shown.
1343                        killAppAtUsersRequest(proc, null);
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1350                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord proc = (ProcessRecord) data.get("app");
1353                    if (proc == null) {
1354                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1355                        break;
1356                    }
1357                    if (proc.crashDialog != null) {
1358                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1359                        return;
1360                    }
1361                    AppErrorResult res = (AppErrorResult) data.get("result");
1362                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1363                        Dialog d = new StrictModeViolationDialog(mContext,
1364                                ActivityManagerService.this, res, proc);
1365                        d.show();
1366                        proc.crashDialog = d;
1367                    } else {
1368                        // The device is asleep, so just pretend that the user
1369                        // saw a crash dialog and hit "force quit".
1370                        res.set(0);
1371                    }
1372                }
1373                ensureBootCompleted();
1374            } break;
1375            case SHOW_FACTORY_ERROR_MSG: {
1376                Dialog d = new FactoryErrorDialog(
1377                    mContext, msg.getData().getCharSequence("msg"));
1378                d.show();
1379                ensureBootCompleted();
1380            } break;
1381            case UPDATE_CONFIGURATION_MSG: {
1382                final ContentResolver resolver = mContext.getContentResolver();
1383                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1384            } break;
1385            case GC_BACKGROUND_PROCESSES_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    performAppGcsIfAppropriateLocked();
1388                }
1389            } break;
1390            case WAIT_FOR_DEBUGGER_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    ProcessRecord app = (ProcessRecord)msg.obj;
1393                    if (msg.arg1 != 0) {
1394                        if (!app.waitedForDebugger) {
1395                            Dialog d = new AppWaitingForDebuggerDialog(
1396                                    ActivityManagerService.this,
1397                                    mContext, app);
1398                            app.waitDialog = d;
1399                            app.waitedForDebugger = true;
1400                            d.show();
1401                        }
1402                    } else {
1403                        if (app.waitDialog != null) {
1404                            app.waitDialog.dismiss();
1405                            app.waitDialog = null;
1406                        }
1407                    }
1408                }
1409            } break;
1410            case SERVICE_TIMEOUT_MSG: {
1411                if (mDidDexOpt) {
1412                    mDidDexOpt = false;
1413                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1414                    nmsg.obj = msg.obj;
1415                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1416                    return;
1417                }
1418                mServices.serviceTimeout((ProcessRecord)msg.obj);
1419            } break;
1420            case UPDATE_TIME_ZONE: {
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.updateTimeZone();
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case CLEAR_DNS_CACHE_MSG: {
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.clearDnsCache();
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case UPDATE_HTTP_PROXY_MSG: {
1449                ProxyInfo proxy = (ProxyInfo)msg.obj;
1450                String host = "";
1451                String port = "";
1452                String exclList = "";
1453                Uri pacFileUrl = Uri.EMPTY;
1454                if (proxy != null) {
1455                    host = proxy.getHost();
1456                    port = Integer.toString(proxy.getPort());
1457                    exclList = proxy.getExclusionListAsString();
1458                    pacFileUrl = proxy.getPacFileUrl();
1459                }
1460                synchronized (ActivityManagerService.this) {
1461                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                        ProcessRecord r = mLruProcesses.get(i);
1463                        if (r.thread != null) {
1464                            try {
1465                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1466                            } catch (RemoteException ex) {
1467                                Slog.w(TAG, "Failed to update http proxy for: " +
1468                                        r.info.processName);
1469                            }
1470                        }
1471                    }
1472                }
1473            } break;
1474            case SHOW_UID_ERROR_MSG: {
1475                if (mShowDialogs) {
1476                    AlertDialog d = new BaseErrorDialog(mContext);
1477                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1478                    d.setCancelable(false);
1479                    d.setTitle(mContext.getText(R.string.android_system_label));
1480                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1481                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1482                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1483                    d.show();
1484                }
1485            } break;
1486            case SHOW_FINGERPRINT_ERROR_MSG: {
1487                if (mShowDialogs) {
1488                    AlertDialog d = new BaseErrorDialog(mContext);
1489                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1490                    d.setCancelable(false);
1491                    d.setTitle(mContext.getText(R.string.android_system_label));
1492                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1493                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1494                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1495                    d.show();
1496                }
1497            } break;
1498            case PROC_START_TIMEOUT_MSG: {
1499                if (mDidDexOpt) {
1500                    mDidDexOpt = false;
1501                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1502                    nmsg.obj = msg.obj;
1503                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1504                    return;
1505                }
1506                ProcessRecord app = (ProcessRecord)msg.obj;
1507                synchronized (ActivityManagerService.this) {
1508                    processStartTimedOutLocked(app);
1509                }
1510            } break;
1511            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1514                }
1515            } break;
1516            case KILL_APPLICATION_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    int appid = msg.arg1;
1519                    boolean restart = (msg.arg2 == 1);
1520                    Bundle bundle = (Bundle)msg.obj;
1521                    String pkg = bundle.getString("pkg");
1522                    String reason = bundle.getString("reason");
1523                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1524                            false, UserHandle.USER_ALL, reason);
1525                }
1526            } break;
1527            case FINALIZE_PENDING_INTENT_MSG: {
1528                ((PendingIntentRecord)msg.obj).completeFinalize();
1529            } break;
1530            case POST_HEAVY_NOTIFICATION_MSG: {
1531                INotificationManager inm = NotificationManager.getService();
1532                if (inm == null) {
1533                    return;
1534                }
1535
1536                ActivityRecord root = (ActivityRecord)msg.obj;
1537                ProcessRecord process = root.app;
1538                if (process == null) {
1539                    return;
1540                }
1541
1542                try {
1543                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1544                    String text = mContext.getString(R.string.heavy_weight_notification,
1545                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1546                    Notification notification = new Notification();
1547                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1548                    notification.when = 0;
1549                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1550                    notification.tickerText = text;
1551                    notification.defaults = 0; // please be quiet
1552                    notification.sound = null;
1553                    notification.vibrate = null;
1554                    notification.color = mContext.getResources().getColor(
1555                            com.android.internal.R.color.system_notification_accent_color);
1556                    notification.setLatestEventInfo(context, text,
1557                            mContext.getText(R.string.heavy_weight_notification_detail),
1558                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1559                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1560                                    new UserHandle(root.userId)));
1561
1562                    try {
1563                        int[] outId = new int[1];
1564                        inm.enqueueNotificationWithTag("android", "android", null,
1565                                R.string.heavy_weight_notification,
1566                                notification, outId, root.userId);
1567                    } catch (RuntimeException e) {
1568                        Slog.w(ActivityManagerService.TAG,
1569                                "Error showing notification for heavy-weight app", e);
1570                    } catch (RemoteException e) {
1571                    }
1572                } catch (NameNotFoundException e) {
1573                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1574                }
1575            } break;
1576            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1577                INotificationManager inm = NotificationManager.getService();
1578                if (inm == null) {
1579                    return;
1580                }
1581                try {
1582                    inm.cancelNotificationWithTag("android", null,
1583                            R.string.heavy_weight_notification,  msg.arg1);
1584                } catch (RuntimeException e) {
1585                    Slog.w(ActivityManagerService.TAG,
1586                            "Error canceling notification for service", e);
1587                } catch (RemoteException e) {
1588                }
1589            } break;
1590            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1591                synchronized (ActivityManagerService.this) {
1592                    checkExcessivePowerUsageLocked(true);
1593                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1594                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1595                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1596                }
1597            } break;
1598            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1599                synchronized (ActivityManagerService.this) {
1600                    ActivityRecord ar = (ActivityRecord)msg.obj;
1601                    if (mCompatModeDialog != null) {
1602                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1603                                ar.info.applicationInfo.packageName)) {
1604                            return;
1605                        }
1606                        mCompatModeDialog.dismiss();
1607                        mCompatModeDialog = null;
1608                    }
1609                    if (ar != null && false) {
1610                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1611                                ar.packageName)) {
1612                            int mode = mCompatModePackages.computeCompatModeLocked(
1613                                    ar.info.applicationInfo);
1614                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1615                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1616                                mCompatModeDialog = new CompatModeDialog(
1617                                        ActivityManagerService.this, mContext,
1618                                        ar.info.applicationInfo);
1619                                mCompatModeDialog.show();
1620                            }
1621                        }
1622                    }
1623                }
1624                break;
1625            }
1626            case DISPATCH_PROCESSES_CHANGED: {
1627                dispatchProcessesChanged();
1628                break;
1629            }
1630            case DISPATCH_PROCESS_DIED: {
1631                final int pid = msg.arg1;
1632                final int uid = msg.arg2;
1633                dispatchProcessDied(pid, uid);
1634                break;
1635            }
1636            case REPORT_MEM_USAGE_MSG: {
1637                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1638                Thread thread = new Thread() {
1639                    @Override public void run() {
1640                        reportMemUsage(memInfos);
1641                    }
1642                };
1643                thread.start();
1644                break;
1645            }
1646            case START_USER_SWITCH_MSG: {
1647                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1648                break;
1649            }
1650            case REPORT_USER_SWITCH_MSG: {
1651                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case CONTINUE_USER_SWITCH_MSG: {
1655                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case USER_SWITCH_TIMEOUT_MSG: {
1659                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case IMMERSIVE_MODE_LOCK_MSG: {
1663                final boolean nextState = (msg.arg1 != 0);
1664                if (mUpdateLock.isHeld() != nextState) {
1665                    if (DEBUG_IMMERSIVE) {
1666                        final ActivityRecord r = (ActivityRecord) msg.obj;
1667                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1668                    }
1669                    if (nextState) {
1670                        mUpdateLock.acquire();
1671                    } else {
1672                        mUpdateLock.release();
1673                    }
1674                }
1675                break;
1676            }
1677            case PERSIST_URI_GRANTS_MSG: {
1678                writeGrantedUriPermissions();
1679                break;
1680            }
1681            case REQUEST_ALL_PSS_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1684                }
1685                break;
1686            }
1687            case START_PROFILES_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    startProfilesLocked();
1690                }
1691                break;
1692            }
1693            case UPDATE_TIME: {
1694                synchronized (ActivityManagerService.this) {
1695                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1696                        ProcessRecord r = mLruProcesses.get(i);
1697                        if (r.thread != null) {
1698                            try {
1699                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1700                            } catch (RemoteException ex) {
1701                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1702                            }
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case SYSTEM_USER_START_MSG: {
1709                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.startUser(msg.arg1);
1712                break;
1713            }
1714            case SYSTEM_USER_CURRENT_MSG: {
1715                mBatteryStatsService.noteEvent(
1716                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1717                        Integer.toString(msg.arg2), msg.arg2);
1718                mBatteryStatsService.noteEvent(
1719                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1720                        Integer.toString(msg.arg1), msg.arg1);
1721                mSystemServiceManager.switchUser(msg.arg1);
1722                break;
1723            }
1724            case ENTER_ANIMATION_COMPLETE_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1727                    if (r != null && r.app != null && r.app.thread != null) {
1728                        try {
1729                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1730                        } catch (RemoteException e) {
1731                        }
1732                    }
1733                }
1734                break;
1735            }
1736            case FINISH_BOOTING_MSG: {
1737                if (msg.arg1 != 0) {
1738                    finishBooting();
1739                }
1740                if (msg.arg2 != 0) {
1741                    enableScreenAfterBoot();
1742                }
1743                break;
1744            }
1745            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1746                try {
1747                    Locale l = (Locale) msg.obj;
1748                    IBinder service = ServiceManager.getService("mount");
1749                    IMountService mountService = IMountService.Stub.asInterface(service);
1750                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1751                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1752                } catch (RemoteException e) {
1753                    Log.e(TAG, "Error storing locale for decryption UI", e);
1754                }
1755                break;
1756            }
1757            case DISMISS_DIALOG_MSG: {
1758                final Dialog d = (Dialog) msg.obj;
1759                d.dismiss();
1760                break;
1761            }
1762            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    int i = mTaskStackListeners.beginBroadcast();
1765                    while (i > 0) {
1766                        i--;
1767                        try {
1768                            // Make a one-way callback to the listener
1769                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1770                        } catch (RemoteException e){
1771                            // Handled by the RemoteCallbackList
1772                        }
1773                    }
1774                    mTaskStackListeners.finishBroadcast();
1775                }
1776                break;
1777            }
1778            }
1779        }
1780    };
1781
1782    static final int COLLECT_PSS_BG_MSG = 1;
1783
1784    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case COLLECT_PSS_BG_MSG: {
1789                long start = SystemClock.uptimeMillis();
1790                MemInfoReader memInfo = null;
1791                synchronized (ActivityManagerService.this) {
1792                    if (mFullPssPending) {
1793                        mFullPssPending = false;
1794                        memInfo = new MemInfoReader();
1795                    }
1796                }
1797                if (memInfo != null) {
1798                    updateCpuStatsNow();
1799                    long nativeTotalPss = 0;
1800                    synchronized (mProcessCpuTracker) {
1801                        final int N = mProcessCpuTracker.countStats();
1802                        for (int j=0; j<N; j++) {
1803                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1804                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1805                                // This is definitely an application process; skip it.
1806                                continue;
1807                            }
1808                            synchronized (mPidsSelfLocked) {
1809                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1810                                    // This is one of our own processes; skip it.
1811                                    continue;
1812                                }
1813                            }
1814                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1815                        }
1816                    }
1817                    memInfo.readMemInfo();
1818                    synchronized (ActivityManagerService.this) {
1819                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1820                                + (SystemClock.uptimeMillis()-start) + "ms");
1821                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1822                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1823                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1824                    }
1825                }
1826
1827                int num = 0;
1828                long[] tmp = new long[1];
1829                do {
1830                    ProcessRecord proc;
1831                    int procState;
1832                    int pid;
1833                    long lastPssTime;
1834                    synchronized (ActivityManagerService.this) {
1835                        if (mPendingPssProcesses.size() <= 0) {
1836                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1837                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1838                            mPendingPssProcesses.clear();
1839                            return;
1840                        }
1841                        proc = mPendingPssProcesses.remove(0);
1842                        procState = proc.pssProcState;
1843                        lastPssTime = proc.lastPssTime;
1844                        if (proc.thread != null && procState == proc.setProcState
1845                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1846                                        < SystemClock.uptimeMillis()) {
1847                            pid = proc.pid;
1848                        } else {
1849                            proc = null;
1850                            pid = 0;
1851                        }
1852                    }
1853                    if (proc != null) {
1854                        long pss = Debug.getPss(pid, tmp, null);
1855                        synchronized (ActivityManagerService.this) {
1856                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1857                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1858                                num++;
1859                                recordPssSample(proc, procState, pss, tmp[0],
1860                                        SystemClock.uptimeMillis());
1861                            }
1862                        }
1863                    }
1864                } while (true);
1865            }
1866            }
1867        }
1868    };
1869
1870    public void setSystemProcess() {
1871        try {
1872            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1873            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1874            ServiceManager.addService("meminfo", new MemBinder(this));
1875            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1876            ServiceManager.addService("dbinfo", new DbBinder(this));
1877            if (MONITOR_CPU_USAGE) {
1878                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1879            }
1880            ServiceManager.addService("permission", new PermissionController(this));
1881
1882            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1883                    "android", STOCK_PM_FLAGS);
1884            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1885
1886            synchronized (this) {
1887                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1888                app.persistent = true;
1889                app.pid = MY_PID;
1890                app.maxAdj = ProcessList.SYSTEM_ADJ;
1891                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1892                mProcessNames.put(app.processName, app.uid, app);
1893                synchronized (mPidsSelfLocked) {
1894                    mPidsSelfLocked.put(app.pid, app);
1895                }
1896                updateLruProcessLocked(app, false, null);
1897                updateOomAdjLocked();
1898            }
1899        } catch (PackageManager.NameNotFoundException e) {
1900            throw new RuntimeException(
1901                    "Unable to find android system package", e);
1902        }
1903    }
1904
1905    public void setWindowManager(WindowManagerService wm) {
1906        mWindowManager = wm;
1907        mStackSupervisor.setWindowManager(wm);
1908    }
1909
1910    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1911        mUsageStatsService = usageStatsManager;
1912    }
1913
1914    public void startObservingNativeCrashes() {
1915        final NativeCrashListener ncl = new NativeCrashListener(this);
1916        ncl.start();
1917    }
1918
1919    public IAppOpsService getAppOpsService() {
1920        return mAppOpsService;
1921    }
1922
1923    static class MemBinder extends Binder {
1924        ActivityManagerService mActivityManagerService;
1925        MemBinder(ActivityManagerService activityManagerService) {
1926            mActivityManagerService = activityManagerService;
1927        }
1928
1929        @Override
1930        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1931            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1932                    != PackageManager.PERMISSION_GRANTED) {
1933                pw.println("Permission Denial: can't dump meminfo from from pid="
1934                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1935                        + " without permission " + android.Manifest.permission.DUMP);
1936                return;
1937            }
1938
1939            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1940        }
1941    }
1942
1943    static class GraphicsBinder extends Binder {
1944        ActivityManagerService mActivityManagerService;
1945        GraphicsBinder(ActivityManagerService activityManagerService) {
1946            mActivityManagerService = activityManagerService;
1947        }
1948
1949        @Override
1950        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1951            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1952                    != PackageManager.PERMISSION_GRANTED) {
1953                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1954                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1955                        + " without permission " + android.Manifest.permission.DUMP);
1956                return;
1957            }
1958
1959            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1960        }
1961    }
1962
1963    static class DbBinder extends Binder {
1964        ActivityManagerService mActivityManagerService;
1965        DbBinder(ActivityManagerService activityManagerService) {
1966            mActivityManagerService = activityManagerService;
1967        }
1968
1969        @Override
1970        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1971            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1972                    != PackageManager.PERMISSION_GRANTED) {
1973                pw.println("Permission Denial: can't dump dbinfo from from pid="
1974                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1975                        + " without permission " + android.Manifest.permission.DUMP);
1976                return;
1977            }
1978
1979            mActivityManagerService.dumpDbInfo(fd, pw, args);
1980        }
1981    }
1982
1983    static class CpuBinder extends Binder {
1984        ActivityManagerService mActivityManagerService;
1985        CpuBinder(ActivityManagerService activityManagerService) {
1986            mActivityManagerService = activityManagerService;
1987        }
1988
1989        @Override
1990        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1991            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1992                    != PackageManager.PERMISSION_GRANTED) {
1993                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1994                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1995                        + " without permission " + android.Manifest.permission.DUMP);
1996                return;
1997            }
1998
1999            synchronized (mActivityManagerService.mProcessCpuTracker) {
2000                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2001                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2002                        SystemClock.uptimeMillis()));
2003            }
2004        }
2005    }
2006
2007    public static final class Lifecycle extends SystemService {
2008        private final ActivityManagerService mService;
2009
2010        public Lifecycle(Context context) {
2011            super(context);
2012            mService = new ActivityManagerService(context);
2013        }
2014
2015        @Override
2016        public void onStart() {
2017            mService.start();
2018        }
2019
2020        public ActivityManagerService getService() {
2021            return mService;
2022        }
2023    }
2024
2025    // Note: This method is invoked on the main thread but may need to attach various
2026    // handlers to other threads.  So take care to be explicit about the looper.
2027    public ActivityManagerService(Context systemContext) {
2028        mContext = systemContext;
2029        mFactoryTest = FactoryTest.getMode();
2030        mSystemThread = ActivityThread.currentActivityThread();
2031
2032        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2033
2034        mHandlerThread = new ServiceThread(TAG,
2035                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2036        mHandlerThread.start();
2037        mHandler = new MainHandler(mHandlerThread.getLooper());
2038
2039        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "foreground", BROADCAST_FG_TIMEOUT, false);
2041        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2042                "background", BROADCAST_BG_TIMEOUT, true);
2043        mBroadcastQueues[0] = mFgBroadcastQueue;
2044        mBroadcastQueues[1] = mBgBroadcastQueue;
2045
2046        mServices = new ActiveServices(this);
2047        mProviderMap = new ProviderMap(this);
2048
2049        // TODO: Move creation of battery stats service outside of activity manager service.
2050        File dataDir = Environment.getDataDirectory();
2051        File systemDir = new File(dataDir, "system");
2052        systemDir.mkdirs();
2053        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2054        mBatteryStatsService.getActiveStatistics().readLocked();
2055        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2056        mOnBattery = DEBUG_POWER ? true
2057                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2058        mBatteryStatsService.getActiveStatistics().setCallback(this);
2059
2060        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2061
2062        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2063
2064        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2065
2066        // User 0 is the first and only user that runs at boot.
2067        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2068        mUserLru.add(Integer.valueOf(0));
2069        updateStartedUserArrayLocked();
2070
2071        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2072            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2073
2074        mConfiguration.setToDefaults();
2075        mConfiguration.setLocale(Locale.getDefault());
2076
2077        mConfigurationSeq = mConfiguration.seq = 1;
2078        mProcessCpuTracker.init();
2079
2080        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2081        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2082        mStackSupervisor = new ActivityStackSupervisor(this);
2083        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2084
2085        mProcessCpuThread = new Thread("CpuTracker") {
2086            @Override
2087            public void run() {
2088                while (true) {
2089                    try {
2090                        try {
2091                            synchronized(this) {
2092                                final long now = SystemClock.uptimeMillis();
2093                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2094                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2095                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2096                                //        + ", write delay=" + nextWriteDelay);
2097                                if (nextWriteDelay < nextCpuDelay) {
2098                                    nextCpuDelay = nextWriteDelay;
2099                                }
2100                                if (nextCpuDelay > 0) {
2101                                    mProcessCpuMutexFree.set(true);
2102                                    this.wait(nextCpuDelay);
2103                                }
2104                            }
2105                        } catch (InterruptedException e) {
2106                        }
2107                        updateCpuStatsNow();
2108                    } catch (Exception e) {
2109                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2110                    }
2111                }
2112            }
2113        };
2114
2115        Watchdog.getInstance().addMonitor(this);
2116        Watchdog.getInstance().addThread(mHandler);
2117    }
2118
2119    public void setSystemServiceManager(SystemServiceManager mgr) {
2120        mSystemServiceManager = mgr;
2121    }
2122
2123    public void setInstaller(Installer installer) {
2124        mInstaller = installer;
2125    }
2126
2127    private void start() {
2128        Process.removeAllProcessGroups();
2129        mProcessCpuThread.start();
2130
2131        mBatteryStatsService.publish(mContext);
2132        mAppOpsService.publish(mContext);
2133        Slog.d("AppOps", "AppOpsService published");
2134        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2135    }
2136
2137    public void initPowerManagement() {
2138        mStackSupervisor.initPowerManagement();
2139        mBatteryStatsService.initPowerManagement();
2140    }
2141
2142    @Override
2143    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2144            throws RemoteException {
2145        if (code == SYSPROPS_TRANSACTION) {
2146            // We need to tell all apps about the system property change.
2147            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2148            synchronized(this) {
2149                final int NP = mProcessNames.getMap().size();
2150                for (int ip=0; ip<NP; ip++) {
2151                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2152                    final int NA = apps.size();
2153                    for (int ia=0; ia<NA; ia++) {
2154                        ProcessRecord app = apps.valueAt(ia);
2155                        if (app.thread != null) {
2156                            procs.add(app.thread.asBinder());
2157                        }
2158                    }
2159                }
2160            }
2161
2162            int N = procs.size();
2163            for (int i=0; i<N; i++) {
2164                Parcel data2 = Parcel.obtain();
2165                try {
2166                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2167                } catch (RemoteException e) {
2168                }
2169                data2.recycle();
2170            }
2171        }
2172        try {
2173            return super.onTransact(code, data, reply, flags);
2174        } catch (RuntimeException e) {
2175            // The activity manager only throws security exceptions, so let's
2176            // log all others.
2177            if (!(e instanceof SecurityException)) {
2178                Slog.wtf(TAG, "Activity Manager Crash", e);
2179            }
2180            throw e;
2181        }
2182    }
2183
2184    void updateCpuStats() {
2185        final long now = SystemClock.uptimeMillis();
2186        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2187            return;
2188        }
2189        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2190            synchronized (mProcessCpuThread) {
2191                mProcessCpuThread.notify();
2192            }
2193        }
2194    }
2195
2196    void updateCpuStatsNow() {
2197        synchronized (mProcessCpuTracker) {
2198            mProcessCpuMutexFree.set(false);
2199            final long now = SystemClock.uptimeMillis();
2200            boolean haveNewCpuStats = false;
2201
2202            if (MONITOR_CPU_USAGE &&
2203                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2204                mLastCpuTime.set(now);
2205                haveNewCpuStats = true;
2206                mProcessCpuTracker.update();
2207                //Slog.i(TAG, mProcessCpu.printCurrentState());
2208                //Slog.i(TAG, "Total CPU usage: "
2209                //        + mProcessCpu.getTotalCpuPercent() + "%");
2210
2211                // Slog the cpu usage if the property is set.
2212                if ("true".equals(SystemProperties.get("events.cpu"))) {
2213                    int user = mProcessCpuTracker.getLastUserTime();
2214                    int system = mProcessCpuTracker.getLastSystemTime();
2215                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2216                    int irq = mProcessCpuTracker.getLastIrqTime();
2217                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2218                    int idle = mProcessCpuTracker.getLastIdleTime();
2219
2220                    int total = user + system + iowait + irq + softIrq + idle;
2221                    if (total == 0) total = 1;
2222
2223                    EventLog.writeEvent(EventLogTags.CPU,
2224                            ((user+system+iowait+irq+softIrq) * 100) / total,
2225                            (user * 100) / total,
2226                            (system * 100) / total,
2227                            (iowait * 100) / total,
2228                            (irq * 100) / total,
2229                            (softIrq * 100) / total);
2230                }
2231            }
2232
2233            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2234            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2235            synchronized(bstats) {
2236                synchronized(mPidsSelfLocked) {
2237                    if (haveNewCpuStats) {
2238                        if (mOnBattery) {
2239                            int perc = bstats.startAddingCpuLocked();
2240                            int totalUTime = 0;
2241                            int totalSTime = 0;
2242                            final int N = mProcessCpuTracker.countStats();
2243                            for (int i=0; i<N; i++) {
2244                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2245                                if (!st.working) {
2246                                    continue;
2247                                }
2248                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2249                                int otherUTime = (st.rel_utime*perc)/100;
2250                                int otherSTime = (st.rel_stime*perc)/100;
2251                                totalUTime += otherUTime;
2252                                totalSTime += otherSTime;
2253                                if (pr != null) {
2254                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2255                                    if (ps == null || !ps.isActive()) {
2256                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2257                                                pr.info.uid, pr.processName);
2258                                    }
2259                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2260                                            st.rel_stime-otherSTime);
2261                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2262                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2263                                } else {
2264                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2265                                    if (ps == null || !ps.isActive()) {
2266                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2267                                                bstats.mapUid(st.uid), st.name);
2268                                    }
2269                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2270                                            st.rel_stime-otherSTime);
2271                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2272                                }
2273                            }
2274                            bstats.finishAddingCpuLocked(perc, totalUTime,
2275                                    totalSTime, cpuSpeedTimes);
2276                        }
2277                    }
2278                }
2279
2280                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2281                    mLastWriteTime = now;
2282                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2283                }
2284            }
2285        }
2286    }
2287
2288    @Override
2289    public void batteryNeedsCpuUpdate() {
2290        updateCpuStatsNow();
2291    }
2292
2293    @Override
2294    public void batteryPowerChanged(boolean onBattery) {
2295        // When plugging in, update the CPU stats first before changing
2296        // the plug state.
2297        updateCpuStatsNow();
2298        synchronized (this) {
2299            synchronized(mPidsSelfLocked) {
2300                mOnBattery = DEBUG_POWER ? true : onBattery;
2301            }
2302        }
2303    }
2304
2305    /**
2306     * Initialize the application bind args. These are passed to each
2307     * process when the bindApplication() IPC is sent to the process. They're
2308     * lazily setup to make sure the services are running when they're asked for.
2309     */
2310    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2311        if (mAppBindArgs == null) {
2312            mAppBindArgs = new HashMap<>();
2313
2314            // Isolated processes won't get this optimization, so that we don't
2315            // violate the rules about which services they have access to.
2316            if (!isolated) {
2317                // Setup the application init args
2318                mAppBindArgs.put("package", ServiceManager.getService("package"));
2319                mAppBindArgs.put("window", ServiceManager.getService("window"));
2320                mAppBindArgs.put(Context.ALARM_SERVICE,
2321                        ServiceManager.getService(Context.ALARM_SERVICE));
2322            }
2323        }
2324        return mAppBindArgs;
2325    }
2326
2327    final void setFocusedActivityLocked(ActivityRecord r) {
2328        if (mFocusedActivity != r) {
2329            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2330            mFocusedActivity = r;
2331            if (r.task != null && r.task.voiceInteractor != null) {
2332                startRunningVoiceLocked();
2333            } else {
2334                finishRunningVoiceLocked();
2335            }
2336            mStackSupervisor.setFocusedStack(r);
2337            if (r != null) {
2338                mWindowManager.setFocusedApp(r.appToken, true);
2339            }
2340            applyUpdateLockStateLocked(r);
2341        }
2342    }
2343
2344    final void clearFocusedActivity(ActivityRecord r) {
2345        if (mFocusedActivity == r) {
2346            mFocusedActivity = null;
2347        }
2348    }
2349
2350    @Override
2351    public void setFocusedStack(int stackId) {
2352        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2353        synchronized (ActivityManagerService.this) {
2354            ActivityStack stack = mStackSupervisor.getStack(stackId);
2355            if (stack != null) {
2356                ActivityRecord r = stack.topRunningActivityLocked(null);
2357                if (r != null) {
2358                    setFocusedActivityLocked(r);
2359                }
2360            }
2361        }
2362    }
2363
2364    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2365    @Override
2366    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2367        synchronized (ActivityManagerService.this) {
2368            if (listener != null) {
2369                mTaskStackListeners.register(listener);
2370            }
2371        }
2372    }
2373
2374    @Override
2375    public void notifyActivityDrawn(IBinder token) {
2376        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2377        synchronized (this) {
2378            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2379            if (r != null) {
2380                r.task.stack.notifyActivityDrawnLocked(r);
2381            }
2382        }
2383    }
2384
2385    final void applyUpdateLockStateLocked(ActivityRecord r) {
2386        // Modifications to the UpdateLock state are done on our handler, outside
2387        // the activity manager's locks.  The new state is determined based on the
2388        // state *now* of the relevant activity record.  The object is passed to
2389        // the handler solely for logging detail, not to be consulted/modified.
2390        final boolean nextState = r != null && r.immersive;
2391        mHandler.sendMessage(
2392                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2393    }
2394
2395    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2396        Message msg = Message.obtain();
2397        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2398        msg.obj = r.task.askedCompatMode ? null : r;
2399        mHandler.sendMessage(msg);
2400    }
2401
2402    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2403            String what, Object obj, ProcessRecord srcApp) {
2404        app.lastActivityTime = now;
2405
2406        if (app.activities.size() > 0) {
2407            // Don't want to touch dependent processes that are hosting activities.
2408            return index;
2409        }
2410
2411        int lrui = mLruProcesses.lastIndexOf(app);
2412        if (lrui < 0) {
2413            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2414                    + what + " " + obj + " from " + srcApp);
2415            return index;
2416        }
2417
2418        if (lrui >= index) {
2419            // Don't want to cause this to move dependent processes *back* in the
2420            // list as if they were less frequently used.
2421            return index;
2422        }
2423
2424        if (lrui >= mLruProcessActivityStart) {
2425            // Don't want to touch dependent processes that are hosting activities.
2426            return index;
2427        }
2428
2429        mLruProcesses.remove(lrui);
2430        if (index > 0) {
2431            index--;
2432        }
2433        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2434                + " in LRU list: " + app);
2435        mLruProcesses.add(index, app);
2436        return index;
2437    }
2438
2439    final void removeLruProcessLocked(ProcessRecord app) {
2440        int lrui = mLruProcesses.lastIndexOf(app);
2441        if (lrui >= 0) {
2442            if (!app.killed) {
2443                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2444                Process.killProcessQuiet(app.pid);
2445                Process.killProcessGroup(app.info.uid, app.pid);
2446            }
2447            if (lrui <= mLruProcessActivityStart) {
2448                mLruProcessActivityStart--;
2449            }
2450            if (lrui <= mLruProcessServiceStart) {
2451                mLruProcessServiceStart--;
2452            }
2453            mLruProcesses.remove(lrui);
2454        }
2455    }
2456
2457    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2458            ProcessRecord client) {
2459        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2460                || app.treatLikeActivity;
2461        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2462        if (!activityChange && hasActivity) {
2463            // The process has activities, so we are only allowing activity-based adjustments
2464            // to move it.  It should be kept in the front of the list with other
2465            // processes that have activities, and we don't want those to change their
2466            // order except due to activity operations.
2467            return;
2468        }
2469
2470        mLruSeq++;
2471        final long now = SystemClock.uptimeMillis();
2472        app.lastActivityTime = now;
2473
2474        // First a quick reject: if the app is already at the position we will
2475        // put it, then there is nothing to do.
2476        if (hasActivity) {
2477            final int N = mLruProcesses.size();
2478            if (N > 0 && mLruProcesses.get(N-1) == app) {
2479                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2480                return;
2481            }
2482        } else {
2483            if (mLruProcessServiceStart > 0
2484                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2485                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2486                return;
2487            }
2488        }
2489
2490        int lrui = mLruProcesses.lastIndexOf(app);
2491
2492        if (app.persistent && lrui >= 0) {
2493            // We don't care about the position of persistent processes, as long as
2494            // they are in the list.
2495            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2496            return;
2497        }
2498
2499        /* In progress: compute new position first, so we can avoid doing work
2500           if the process is not actually going to move.  Not yet working.
2501        int addIndex;
2502        int nextIndex;
2503        boolean inActivity = false, inService = false;
2504        if (hasActivity) {
2505            // Process has activities, put it at the very tipsy-top.
2506            addIndex = mLruProcesses.size();
2507            nextIndex = mLruProcessServiceStart;
2508            inActivity = true;
2509        } else if (hasService) {
2510            // Process has services, put it at the top of the service list.
2511            addIndex = mLruProcessActivityStart;
2512            nextIndex = mLruProcessServiceStart;
2513            inActivity = true;
2514            inService = true;
2515        } else  {
2516            // Process not otherwise of interest, it goes to the top of the non-service area.
2517            addIndex = mLruProcessServiceStart;
2518            if (client != null) {
2519                int clientIndex = mLruProcesses.lastIndexOf(client);
2520                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2521                        + app);
2522                if (clientIndex >= 0 && addIndex > clientIndex) {
2523                    addIndex = clientIndex;
2524                }
2525            }
2526            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2527        }
2528
2529        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2530                + mLruProcessActivityStart + "): " + app);
2531        */
2532
2533        if (lrui >= 0) {
2534            if (lrui < mLruProcessActivityStart) {
2535                mLruProcessActivityStart--;
2536            }
2537            if (lrui < mLruProcessServiceStart) {
2538                mLruProcessServiceStart--;
2539            }
2540            /*
2541            if (addIndex > lrui) {
2542                addIndex--;
2543            }
2544            if (nextIndex > lrui) {
2545                nextIndex--;
2546            }
2547            */
2548            mLruProcesses.remove(lrui);
2549        }
2550
2551        /*
2552        mLruProcesses.add(addIndex, app);
2553        if (inActivity) {
2554            mLruProcessActivityStart++;
2555        }
2556        if (inService) {
2557            mLruProcessActivityStart++;
2558        }
2559        */
2560
2561        int nextIndex;
2562        if (hasActivity) {
2563            final int N = mLruProcesses.size();
2564            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2565                // Process doesn't have activities, but has clients with
2566                // activities...  move it up, but one below the top (the top
2567                // should always have a real activity).
2568                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2569                mLruProcesses.add(N-1, app);
2570                // To keep it from spamming the LRU list (by making a bunch of clients),
2571                // we will push down any other entries owned by the app.
2572                final int uid = app.info.uid;
2573                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2574                    ProcessRecord subProc = mLruProcesses.get(i);
2575                    if (subProc.info.uid == uid) {
2576                        // We want to push this one down the list.  If the process after
2577                        // it is for the same uid, however, don't do so, because we don't
2578                        // want them internally to be re-ordered.
2579                        if (mLruProcesses.get(i-1).info.uid != uid) {
2580                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2581                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2582                            ProcessRecord tmp = mLruProcesses.get(i);
2583                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2584                            mLruProcesses.set(i-1, tmp);
2585                            i--;
2586                        }
2587                    } else {
2588                        // A gap, we can stop here.
2589                        break;
2590                    }
2591                }
2592            } else {
2593                // Process has activities, put it at the very tipsy-top.
2594                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2595                mLruProcesses.add(app);
2596            }
2597            nextIndex = mLruProcessServiceStart;
2598        } else if (hasService) {
2599            // Process has services, put it at the top of the service list.
2600            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2601            mLruProcesses.add(mLruProcessActivityStart, app);
2602            nextIndex = mLruProcessServiceStart;
2603            mLruProcessActivityStart++;
2604        } else  {
2605            // Process not otherwise of interest, it goes to the top of the non-service area.
2606            int index = mLruProcessServiceStart;
2607            if (client != null) {
2608                // If there is a client, don't allow the process to be moved up higher
2609                // in the list than that client.
2610                int clientIndex = mLruProcesses.lastIndexOf(client);
2611                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2612                        + " when updating " + app);
2613                if (clientIndex <= lrui) {
2614                    // Don't allow the client index restriction to push it down farther in the
2615                    // list than it already is.
2616                    clientIndex = lrui;
2617                }
2618                if (clientIndex >= 0 && index > clientIndex) {
2619                    index = clientIndex;
2620                }
2621            }
2622            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2623            mLruProcesses.add(index, app);
2624            nextIndex = index-1;
2625            mLruProcessActivityStart++;
2626            mLruProcessServiceStart++;
2627        }
2628
2629        // If the app is currently using a content provider or service,
2630        // bump those processes as well.
2631        for (int j=app.connections.size()-1; j>=0; j--) {
2632            ConnectionRecord cr = app.connections.valueAt(j);
2633            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2634                    && cr.binding.service.app != null
2635                    && cr.binding.service.app.lruSeq != mLruSeq
2636                    && !cr.binding.service.app.persistent) {
2637                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2638                        "service connection", cr, app);
2639            }
2640        }
2641        for (int j=app.conProviders.size()-1; j>=0; j--) {
2642            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2643            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2644                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2645                        "provider reference", cpr, app);
2646            }
2647        }
2648    }
2649
2650    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2651        if (uid == Process.SYSTEM_UID) {
2652            // The system gets to run in any process.  If there are multiple
2653            // processes with the same uid, just pick the first (this
2654            // should never happen).
2655            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2656            if (procs == null) return null;
2657            final int N = procs.size();
2658            for (int i = 0; i < N; i++) {
2659                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2660            }
2661        }
2662        ProcessRecord proc = mProcessNames.get(processName, uid);
2663        if (false && proc != null && !keepIfLarge
2664                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2665                && proc.lastCachedPss >= 4000) {
2666            // Turn this condition on to cause killing to happen regularly, for testing.
2667            if (proc.baseProcessTracker != null) {
2668                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2669            }
2670            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2671        } else if (proc != null && !keepIfLarge
2672                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2673                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2674            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2675            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2676                if (proc.baseProcessTracker != null) {
2677                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2678                }
2679                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2680            }
2681        }
2682        return proc;
2683    }
2684
2685    void ensurePackageDexOpt(String packageName) {
2686        IPackageManager pm = AppGlobals.getPackageManager();
2687        try {
2688            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2689                mDidDexOpt = true;
2690            }
2691        } catch (RemoteException e) {
2692        }
2693    }
2694
2695    boolean isNextTransitionForward() {
2696        int transit = mWindowManager.getPendingAppTransition();
2697        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2698                || transit == AppTransition.TRANSIT_TASK_OPEN
2699                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2700    }
2701
2702    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2703            String processName, String abiOverride, int uid, Runnable crashHandler) {
2704        synchronized(this) {
2705            ApplicationInfo info = new ApplicationInfo();
2706            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2707            // For isolated processes, the former contains the parent's uid and the latter the
2708            // actual uid of the isolated process.
2709            // In the special case introduced by this method (which is, starting an isolated
2710            // process directly from the SystemServer without an actual parent app process) the
2711            // closest thing to a parent's uid is SYSTEM_UID.
2712            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2713            // the |isolated| logic in the ProcessRecord constructor.
2714            info.uid = Process.SYSTEM_UID;
2715            info.processName = processName;
2716            info.className = entryPoint;
2717            info.packageName = "android";
2718            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2719                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2720                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2721                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2722                    crashHandler);
2723            return proc != null ? proc.pid : 0;
2724        }
2725    }
2726
2727    final ProcessRecord startProcessLocked(String processName,
2728            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2729            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2730            boolean isolated, boolean keepIfLarge) {
2731        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2732                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2733                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2734                null /* crashHandler */);
2735    }
2736
2737    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2738            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2739            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2740            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2741        long startTime = SystemClock.elapsedRealtime();
2742        ProcessRecord app;
2743        if (!isolated) {
2744            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2745            checkTime(startTime, "startProcess: after getProcessRecord");
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2767                checkTime(startTime, "startProcess: done, added package to proc");
2768                return app;
2769            }
2770
2771            // An application record is attached to a previous process,
2772            // clean it up now.
2773            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2774            checkTime(startTime, "startProcess: bad proc running, killing");
2775            Process.killProcessGroup(app.info.uid, app.pid);
2776            handleAppDiedLocked(app, true, true);
2777            checkTime(startTime, "startProcess: done killing old proc");
2778        }
2779
2780        String hostingNameStr = hostingName != null
2781                ? hostingName.flattenToShortString() : null;
2782
2783        if (!isolated) {
2784            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2785                // If we are in the background, then check to see if this process
2786                // is bad.  If so, we will just silently fail.
2787                if (mBadProcesses.get(info.processName, info.uid) != null) {
2788                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2789                            + "/" + info.processName);
2790                    return null;
2791                }
2792            } else {
2793                // When the user is explicitly starting a process, then clear its
2794                // crash count so that we won't make it bad until they see at
2795                // least one crash dialog again, and make the process good again
2796                // if it had been bad.
2797                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2798                        + "/" + info.processName);
2799                mProcessCrashTimes.remove(info.processName, info.uid);
2800                if (mBadProcesses.get(info.processName, info.uid) != null) {
2801                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2802                            UserHandle.getUserId(info.uid), info.uid,
2803                            info.processName);
2804                    mBadProcesses.remove(info.processName, info.uid);
2805                    if (app != null) {
2806                        app.bad = false;
2807                    }
2808                }
2809            }
2810        }
2811
2812        if (app == null) {
2813            checkTime(startTime, "startProcess: creating new process record");
2814            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2815            if (app == null) {
2816                Slog.w(TAG, "Failed making new process record for "
2817                        + processName + "/" + info.uid + " isolated=" + isolated);
2818                return null;
2819            }
2820            app.crashHandler = crashHandler;
2821            mProcessNames.put(processName, app.uid, app);
2822            if (isolated) {
2823                mIsolatedProcesses.put(app.uid, app);
2824            }
2825            checkTime(startTime, "startProcess: done creating new process record");
2826        } else {
2827            // If this is a new package in the process, add the package to the list
2828            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2829            checkTime(startTime, "startProcess: added package to existing proc");
2830        }
2831
2832        // If the system is not ready yet, then hold off on starting this
2833        // process until it is.
2834        if (!mProcessesReady
2835                && !isAllowedWhileBooting(info)
2836                && !allowWhileBooting) {
2837            if (!mProcessesOnHold.contains(app)) {
2838                mProcessesOnHold.add(app);
2839            }
2840            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2841            checkTime(startTime, "startProcess: returning with proc on hold");
2842            return app;
2843        }
2844
2845        checkTime(startTime, "startProcess: stepping in to startProcess");
2846        startProcessLocked(
2847                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2848        checkTime(startTime, "startProcess: done starting proc!");
2849        return (app.pid != 0) ? app : null;
2850    }
2851
2852    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2853        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2854    }
2855
2856    private final void startProcessLocked(ProcessRecord app,
2857            String hostingType, String hostingNameStr) {
2858        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2859                null /* entryPoint */, null /* entryPointArgs */);
2860    }
2861
2862    private final void startProcessLocked(ProcessRecord app, String hostingType,
2863            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2864        long startTime = SystemClock.elapsedRealtime();
2865        if (app.pid > 0 && app.pid != MY_PID) {
2866            checkTime(startTime, "startProcess: removing from pids map");
2867            synchronized (mPidsSelfLocked) {
2868                mPidsSelfLocked.remove(app.pid);
2869                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2870            }
2871            checkTime(startTime, "startProcess: done removing from pids map");
2872            app.setPid(0);
2873        }
2874
2875        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2876                "startProcessLocked removing on hold: " + app);
2877        mProcessesOnHold.remove(app);
2878
2879        checkTime(startTime, "startProcess: starting to update cpu stats");
2880        updateCpuStats();
2881        checkTime(startTime, "startProcess: done updating cpu stats");
2882
2883        try {
2884            int uid = app.uid;
2885
2886            int[] gids = null;
2887            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2888            if (!app.isolated) {
2889                int[] permGids = null;
2890                try {
2891                    checkTime(startTime, "startProcess: getting gids from package manager");
2892                    final PackageManager pm = mContext.getPackageManager();
2893                    permGids = pm.getPackageGids(app.info.packageName);
2894
2895                    if (Environment.isExternalStorageEmulated()) {
2896                        checkTime(startTime, "startProcess: checking external storage perm");
2897                        if (pm.checkPermission(
2898                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2899                                app.info.packageName) == PERMISSION_GRANTED) {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2901                        } else {
2902                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2903                        }
2904                    }
2905                } catch (PackageManager.NameNotFoundException e) {
2906                    Slog.w(TAG, "Unable to retrieve gids", e);
2907                }
2908
2909                /*
2910                 * Add shared application and profile GIDs so applications can share some
2911                 * resources like shared libraries and access user-wide resources
2912                 */
2913                if (permGids == null) {
2914                    gids = new int[2];
2915                } else {
2916                    gids = new int[permGids.length + 2];
2917                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2918                }
2919                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2920                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2921            }
2922            checkTime(startTime, "startProcess: building args");
2923            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2924                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2925                        && mTopComponent != null
2926                        && app.processName.equals(mTopComponent.getPackageName())) {
2927                    uid = 0;
2928                }
2929                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2930                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2931                    uid = 0;
2932                }
2933            }
2934            int debugFlags = 0;
2935            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2936                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2937                // Also turn on CheckJNI for debuggable apps. It's quite
2938                // awkward to turn on otherwise.
2939                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2940            }
2941            // Run the app in safe mode if its manifest requests so or the
2942            // system is booted in safe mode.
2943            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2944                mSafeMode == true) {
2945                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2946            }
2947            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2948                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2949            }
2950            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2951                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2952            }
2953            if ("1".equals(SystemProperties.get("debug.assert"))) {
2954                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2955            }
2956
2957            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2958            if (requiredAbi == null) {
2959                requiredAbi = Build.SUPPORTED_ABIS[0];
2960            }
2961
2962            String instructionSet = null;
2963            if (app.info.primaryCpuAbi != null) {
2964                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2965            }
2966
2967            // Start the process.  It will either succeed and return a result containing
2968            // the PID of the new process, or else throw a RuntimeException.
2969            boolean isActivityProcess = (entryPoint == null);
2970            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2971            checkTime(startTime, "startProcess: asking zygote to start proc");
2972            Process.ProcessStartResult startResult = Process.start(entryPoint,
2973                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2974                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2975                    app.info.dataDir, entryPointArgs);
2976            checkTime(startTime, "startProcess: returned from zygote!");
2977
2978            if (app.isolated) {
2979                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2980            }
2981            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2982            checkTime(startTime, "startProcess: done updating battery stats");
2983
2984            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2985                    UserHandle.getUserId(uid), startResult.pid, uid,
2986                    app.processName, hostingType,
2987                    hostingNameStr != null ? hostingNameStr : "");
2988
2989            if (app.persistent) {
2990                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2991            }
2992
2993            checkTime(startTime, "startProcess: building log message");
2994            StringBuilder buf = mStringBuilder;
2995            buf.setLength(0);
2996            buf.append("Start proc ");
2997            buf.append(app.processName);
2998            if (!isActivityProcess) {
2999                buf.append(" [");
3000                buf.append(entryPoint);
3001                buf.append("]");
3002            }
3003            buf.append(" for ");
3004            buf.append(hostingType);
3005            if (hostingNameStr != null) {
3006                buf.append(" ");
3007                buf.append(hostingNameStr);
3008            }
3009            buf.append(": pid=");
3010            buf.append(startResult.pid);
3011            buf.append(" uid=");
3012            buf.append(uid);
3013            buf.append(" gids={");
3014            if (gids != null) {
3015                for (int gi=0; gi<gids.length; gi++) {
3016                    if (gi != 0) buf.append(", ");
3017                    buf.append(gids[gi]);
3018
3019                }
3020            }
3021            buf.append("}");
3022            if (requiredAbi != null) {
3023                buf.append(" abi=");
3024                buf.append(requiredAbi);
3025            }
3026            Slog.i(TAG, buf.toString());
3027            app.setPid(startResult.pid);
3028            app.usingWrapper = startResult.usingWrapper;
3029            app.removed = false;
3030            app.killed = false;
3031            app.killedByAm = false;
3032            checkTime(startTime, "startProcess: starting to update pids map");
3033            synchronized (mPidsSelfLocked) {
3034                this.mPidsSelfLocked.put(startResult.pid, app);
3035                if (isActivityProcess) {
3036                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3037                    msg.obj = app;
3038                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3039                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3040                }
3041            }
3042            checkTime(startTime, "startProcess: done updating pids map");
3043        } catch (RuntimeException e) {
3044            // XXX do better error recovery.
3045            app.setPid(0);
3046            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3047            if (app.isolated) {
3048                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3049            }
3050            Slog.e(TAG, "Failure starting process " + app.processName, e);
3051        }
3052    }
3053
3054    void updateUsageStats(ActivityRecord component, boolean resumed) {
3055        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3056        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3057        if (resumed) {
3058            if (mUsageStatsService != null) {
3059                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3060                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3061            }
3062            synchronized (stats) {
3063                stats.noteActivityResumedLocked(component.app.uid);
3064            }
3065        } else {
3066            if (mUsageStatsService != null) {
3067                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3068                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3069            }
3070            synchronized (stats) {
3071                stats.noteActivityPausedLocked(component.app.uid);
3072            }
3073        }
3074    }
3075
3076    Intent getHomeIntent() {
3077        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3078        intent.setComponent(mTopComponent);
3079        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3080            intent.addCategory(Intent.CATEGORY_HOME);
3081        }
3082        return intent;
3083    }
3084
3085    boolean startHomeActivityLocked(int userId) {
3086        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3087                && mTopAction == null) {
3088            // We are running in factory test mode, but unable to find
3089            // the factory test app, so just sit around displaying the
3090            // error message and don't try to start anything.
3091            return false;
3092        }
3093        Intent intent = getHomeIntent();
3094        ActivityInfo aInfo =
3095            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3096        if (aInfo != null) {
3097            intent.setComponent(new ComponentName(
3098                    aInfo.applicationInfo.packageName, aInfo.name));
3099            // Don't do this if the home app is currently being
3100            // instrumented.
3101            aInfo = new ActivityInfo(aInfo);
3102            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3103            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3104                    aInfo.applicationInfo.uid, true);
3105            if (app == null || app.instrumentationClass == null) {
3106                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3107                mStackSupervisor.startHomeActivity(intent, aInfo);
3108            }
3109        }
3110
3111        return true;
3112    }
3113
3114    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3115        ActivityInfo ai = null;
3116        ComponentName comp = intent.getComponent();
3117        try {
3118            if (comp != null) {
3119                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3120            } else {
3121                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3122                        intent,
3123                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3124                            flags, userId);
3125
3126                if (info != null) {
3127                    ai = info.activityInfo;
3128                }
3129            }
3130        } catch (RemoteException e) {
3131            // ignore
3132        }
3133
3134        return ai;
3135    }
3136
3137    /**
3138     * Starts the "new version setup screen" if appropriate.
3139     */
3140    void startSetupActivityLocked() {
3141        // Only do this once per boot.
3142        if (mCheckedForSetup) {
3143            return;
3144        }
3145
3146        // We will show this screen if the current one is a different
3147        // version than the last one shown, and we are not running in
3148        // low-level factory test mode.
3149        final ContentResolver resolver = mContext.getContentResolver();
3150        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3151                Settings.Global.getInt(resolver,
3152                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3153            mCheckedForSetup = true;
3154
3155            // See if we should be showing the platform update setup UI.
3156            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3157            List<ResolveInfo> ris = mContext.getPackageManager()
3158                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3159
3160            // We don't allow third party apps to replace this.
3161            ResolveInfo ri = null;
3162            for (int i=0; ris != null && i<ris.size(); i++) {
3163                if ((ris.get(i).activityInfo.applicationInfo.flags
3164                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3165                    ri = ris.get(i);
3166                    break;
3167                }
3168            }
3169
3170            if (ri != null) {
3171                String vers = ri.activityInfo.metaData != null
3172                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3173                        : null;
3174                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3175                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3176                            Intent.METADATA_SETUP_VERSION);
3177                }
3178                String lastVers = Settings.Secure.getString(
3179                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3180                if (vers != null && !vers.equals(lastVers)) {
3181                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3182                    intent.setComponent(new ComponentName(
3183                            ri.activityInfo.packageName, ri.activityInfo.name));
3184                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3185                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3186                            null);
3187                }
3188            }
3189        }
3190    }
3191
3192    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3193        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3194    }
3195
3196    void enforceNotIsolatedCaller(String caller) {
3197        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3198            throw new SecurityException("Isolated process not allowed to call " + caller);
3199        }
3200    }
3201
3202    void enforceShellRestriction(String restriction, int userHandle) {
3203        if (Binder.getCallingUid() == Process.SHELL_UID) {
3204            if (userHandle < 0
3205                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3206                throw new SecurityException("Shell does not have permission to access user "
3207                        + userHandle);
3208            }
3209        }
3210    }
3211
3212    @Override
3213    public int getFrontActivityScreenCompatMode() {
3214        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3215        synchronized (this) {
3216            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3217        }
3218    }
3219
3220    @Override
3221    public void setFrontActivityScreenCompatMode(int mode) {
3222        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3223                "setFrontActivityScreenCompatMode");
3224        synchronized (this) {
3225            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3226        }
3227    }
3228
3229    @Override
3230    public int getPackageScreenCompatMode(String packageName) {
3231        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3232        synchronized (this) {
3233            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3234        }
3235    }
3236
3237    @Override
3238    public void setPackageScreenCompatMode(String packageName, int mode) {
3239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3240                "setPackageScreenCompatMode");
3241        synchronized (this) {
3242            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3243        }
3244    }
3245
3246    @Override
3247    public boolean getPackageAskScreenCompat(String packageName) {
3248        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3249        synchronized (this) {
3250            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3251        }
3252    }
3253
3254    @Override
3255    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setPackageAskScreenCompat");
3258        synchronized (this) {
3259            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3260        }
3261    }
3262
3263    private void dispatchProcessesChanged() {
3264        int N;
3265        synchronized (this) {
3266            N = mPendingProcessChanges.size();
3267            if (mActiveProcessChanges.length < N) {
3268                mActiveProcessChanges = new ProcessChangeItem[N];
3269            }
3270            mPendingProcessChanges.toArray(mActiveProcessChanges);
3271            mAvailProcessChanges.addAll(mPendingProcessChanges);
3272            mPendingProcessChanges.clear();
3273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3274        }
3275
3276        int i = mProcessObservers.beginBroadcast();
3277        while (i > 0) {
3278            i--;
3279            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3280            if (observer != null) {
3281                try {
3282                    for (int j=0; j<N; j++) {
3283                        ProcessChangeItem item = mActiveProcessChanges[j];
3284                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3285                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3286                                    + item.pid + " uid=" + item.uid + ": "
3287                                    + item.foregroundActivities);
3288                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3289                                    item.foregroundActivities);
3290                        }
3291                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3292                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3293                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3294                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3295                        }
3296                    }
3297                } catch (RemoteException e) {
3298                }
3299            }
3300        }
3301        mProcessObservers.finishBroadcast();
3302    }
3303
3304    private void dispatchProcessDied(int pid, int uid) {
3305        int i = mProcessObservers.beginBroadcast();
3306        while (i > 0) {
3307            i--;
3308            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3309            if (observer != null) {
3310                try {
3311                    observer.onProcessDied(pid, uid);
3312                } catch (RemoteException e) {
3313                }
3314            }
3315        }
3316        mProcessObservers.finishBroadcast();
3317    }
3318
3319    @Override
3320    public final int startActivity(IApplicationThread caller, String callingPackage,
3321            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3322            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3323        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3324            resultWho, requestCode, startFlags, profilerInfo, options,
3325            UserHandle.getCallingUserId());
3326    }
3327
3328    @Override
3329    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3330            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3331            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3332        enforceNotIsolatedCaller("startActivity");
3333        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3334                false, ALLOW_FULL_ONLY, "startActivity", null);
3335        // TODO: Switch to user app stacks here.
3336        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3337                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3338                profilerInfo, null, null, options, userId, null, null);
3339    }
3340
3341    @Override
3342    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3343            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3344            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3345
3346        // This is very dangerous -- it allows you to perform a start activity (including
3347        // permission grants) as any app that may launch one of your own activities.  So
3348        // we will only allow this to be done from activities that are part of the core framework,
3349        // and then only when they are running as the system.
3350        final ActivityRecord sourceRecord;
3351        final int targetUid;
3352        final String targetPackage;
3353        synchronized (this) {
3354            if (resultTo == null) {
3355                throw new SecurityException("Must be called from an activity");
3356            }
3357            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3358            if (sourceRecord == null) {
3359                throw new SecurityException("Called with bad activity token: " + resultTo);
3360            }
3361            if (!sourceRecord.info.packageName.equals("android")) {
3362                throw new SecurityException(
3363                        "Must be called from an activity that is declared in the android package");
3364            }
3365            if (sourceRecord.app == null) {
3366                throw new SecurityException("Called without a process attached to activity");
3367            }
3368            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3369                // This is still okay, as long as this activity is running under the
3370                // uid of the original calling activity.
3371                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3372                    throw new SecurityException(
3373                            "Calling activity in uid " + sourceRecord.app.uid
3374                                    + " must be system uid or original calling uid "
3375                                    + sourceRecord.launchedFromUid);
3376                }
3377            }
3378            targetUid = sourceRecord.launchedFromUid;
3379            targetPackage = sourceRecord.launchedFromPackage;
3380        }
3381
3382        if (userId == UserHandle.USER_NULL) {
3383            userId = UserHandle.getUserId(sourceRecord.app.uid);
3384        }
3385
3386        // TODO: Switch to user app stacks here.
3387        try {
3388            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3389                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3390                    null, null, options, userId, null, null);
3391            return ret;
3392        } catch (SecurityException e) {
3393            // XXX need to figure out how to propagate to original app.
3394            // A SecurityException here is generally actually a fault of the original
3395            // calling activity (such as a fairly granting permissions), so propagate it
3396            // back to them.
3397            /*
3398            StringBuilder msg = new StringBuilder();
3399            msg.append("While launching");
3400            msg.append(intent.toString());
3401            msg.append(": ");
3402            msg.append(e.getMessage());
3403            */
3404            throw e;
3405        }
3406    }
3407
3408    @Override
3409    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3410            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3411            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3412        enforceNotIsolatedCaller("startActivityAndWait");
3413        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3414                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3415        WaitResult res = new WaitResult();
3416        // TODO: Switch to user app stacks here.
3417        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3418                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3419                options, userId, null, null);
3420        return res;
3421    }
3422
3423    @Override
3424    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3425            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3426            int startFlags, Configuration config, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivityWithConfig");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3430        // TODO: Switch to user app stacks here.
3431        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3432                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3433                null, null, config, options, userId, null, null);
3434        return ret;
3435    }
3436
3437    @Override
3438    public int startActivityIntentSender(IApplicationThread caller,
3439            IntentSender intent, Intent fillInIntent, String resolvedType,
3440            IBinder resultTo, String resultWho, int requestCode,
3441            int flagsMask, int flagsValues, Bundle options) {
3442        enforceNotIsolatedCaller("startActivityIntentSender");
3443        // Refuse possible leaked file descriptors
3444        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        IIntentSender sender = intent.getTarget();
3449        if (!(sender instanceof PendingIntentRecord)) {
3450            throw new IllegalArgumentException("Bad PendingIntent object");
3451        }
3452
3453        PendingIntentRecord pir = (PendingIntentRecord)sender;
3454
3455        synchronized (this) {
3456            // If this is coming from the currently resumed activity, it is
3457            // effectively saying that app switches are allowed at this point.
3458            final ActivityStack stack = getFocusedStack();
3459            if (stack.mResumedActivity != null &&
3460                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3461                mAppSwitchesAllowedTime = 0;
3462            }
3463        }
3464        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3465                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3466        return ret;
3467    }
3468
3469    @Override
3470    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3471            Intent intent, String resolvedType, IVoiceInteractionSession session,
3472            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3473            Bundle options, int userId) {
3474        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3475                != PackageManager.PERMISSION_GRANTED) {
3476            String msg = "Permission Denial: startVoiceActivity() from pid="
3477                    + Binder.getCallingPid()
3478                    + ", uid=" + Binder.getCallingUid()
3479                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3480            Slog.w(TAG, msg);
3481            throw new SecurityException(msg);
3482        }
3483        if (session == null || interactor == null) {
3484            throw new NullPointerException("null session or interactor");
3485        }
3486        userId = handleIncomingUser(callingPid, callingUid, userId,
3487                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3488        // TODO: Switch to user app stacks here.
3489        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3490                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3491                null, options, userId, null, null);
3492    }
3493
3494    @Override
3495    public boolean startNextMatchingActivity(IBinder callingActivity,
3496            Intent intent, Bundle options) {
3497        // Refuse possible leaked file descriptors
3498        if (intent != null && intent.hasFileDescriptors() == true) {
3499            throw new IllegalArgumentException("File descriptors passed in Intent");
3500        }
3501
3502        synchronized (this) {
3503            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3504            if (r == null) {
3505                ActivityOptions.abort(options);
3506                return false;
3507            }
3508            if (r.app == null || r.app.thread == null) {
3509                // The caller is not running...  d'oh!
3510                ActivityOptions.abort(options);
3511                return false;
3512            }
3513            intent = new Intent(intent);
3514            // The caller is not allowed to change the data.
3515            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3516            // And we are resetting to find the next component...
3517            intent.setComponent(null);
3518
3519            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3520
3521            ActivityInfo aInfo = null;
3522            try {
3523                List<ResolveInfo> resolves =
3524                    AppGlobals.getPackageManager().queryIntentActivities(
3525                            intent, r.resolvedType,
3526                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3527                            UserHandle.getCallingUserId());
3528
3529                // Look for the original activity in the list...
3530                final int N = resolves != null ? resolves.size() : 0;
3531                for (int i=0; i<N; i++) {
3532                    ResolveInfo rInfo = resolves.get(i);
3533                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3534                            && rInfo.activityInfo.name.equals(r.info.name)) {
3535                        // We found the current one...  the next matching is
3536                        // after it.
3537                        i++;
3538                        if (i<N) {
3539                            aInfo = resolves.get(i).activityInfo;
3540                        }
3541                        if (debug) {
3542                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3543                                    + "/" + r.info.name);
3544                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3545                                    + "/" + aInfo.name);
3546                        }
3547                        break;
3548                    }
3549                }
3550            } catch (RemoteException e) {
3551            }
3552
3553            if (aInfo == null) {
3554                // Nobody who is next!
3555                ActivityOptions.abort(options);
3556                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3557                return false;
3558            }
3559
3560            intent.setComponent(new ComponentName(
3561                    aInfo.applicationInfo.packageName, aInfo.name));
3562            intent.setFlags(intent.getFlags()&~(
3563                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3564                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3565                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3566                    Intent.FLAG_ACTIVITY_NEW_TASK));
3567
3568            // Okay now we need to start the new activity, replacing the
3569            // currently running activity.  This is a little tricky because
3570            // we want to start the new one as if the current one is finished,
3571            // but not finish the current one first so that there is no flicker.
3572            // And thus...
3573            final boolean wasFinishing = r.finishing;
3574            r.finishing = true;
3575
3576            // Propagate reply information over to the new activity.
3577            final ActivityRecord resultTo = r.resultTo;
3578            final String resultWho = r.resultWho;
3579            final int requestCode = r.requestCode;
3580            r.resultTo = null;
3581            if (resultTo != null) {
3582                resultTo.removeResultsLocked(r, resultWho, requestCode);
3583            }
3584
3585            final long origId = Binder.clearCallingIdentity();
3586            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3587                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3588                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3589                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3590            Binder.restoreCallingIdentity(origId);
3591
3592            r.finishing = wasFinishing;
3593            if (res != ActivityManager.START_SUCCESS) {
3594                return false;
3595            }
3596            return true;
3597        }
3598    }
3599
3600    @Override
3601    public final int startActivityFromRecents(int taskId, Bundle options) {
3602        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startActivityFromRecents called without " +
3604                    START_TASKS_FROM_RECENTS;
3605            Slog.w(TAG, msg);
3606            throw new SecurityException(msg);
3607        }
3608        return startActivityFromRecentsInner(taskId, options);
3609    }
3610
3611    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3612        final TaskRecord task;
3613        final int callingUid;
3614        final String callingPackage;
3615        final Intent intent;
3616        final int userId;
3617        synchronized (this) {
3618            task = recentTaskForIdLocked(taskId);
3619            if (task == null) {
3620                throw new IllegalArgumentException("Task " + taskId + " not found.");
3621            }
3622            callingUid = task.mCallingUid;
3623            callingPackage = task.mCallingPackage;
3624            intent = task.intent;
3625            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3626            userId = task.userId;
3627        }
3628        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3629                options, userId, null, task);
3630    }
3631
3632    final int startActivityInPackage(int uid, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo,
3634            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3635            IActivityContainer container, TaskRecord inTask) {
3636
3637        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3638                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3639
3640        // TODO: Switch to user app stacks here.
3641        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3642                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3643                null, null, null, options, userId, container, inTask);
3644        return ret;
3645    }
3646
3647    @Override
3648    public final int startActivities(IApplicationThread caller, String callingPackage,
3649            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3650            int userId) {
3651        enforceNotIsolatedCaller("startActivities");
3652        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3653                false, ALLOW_FULL_ONLY, "startActivity", null);
3654        // TODO: Switch to user app stacks here.
3655        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3656                resolvedTypes, resultTo, options, userId);
3657        return ret;
3658    }
3659
3660    final int startActivitiesInPackage(int uid, String callingPackage,
3661            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3662            Bundle options, int userId) {
3663
3664        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3665                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3666        // TODO: Switch to user app stacks here.
3667        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3668                resultTo, options, userId);
3669        return ret;
3670    }
3671
3672    //explicitly remove thd old information in mRecentTasks when removing existing user.
3673    private void removeRecentTasksForUserLocked(int userId) {
3674        if(userId <= 0) {
3675            Slog.i(TAG, "Can't remove recent task on user " + userId);
3676            return;
3677        }
3678
3679        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3680            TaskRecord tr = mRecentTasks.get(i);
3681            if (tr.userId == userId) {
3682                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3683                        + " when finishing user" + userId);
3684                mRecentTasks.remove(i);
3685                tr.removedFromRecents();
3686            }
3687        }
3688
3689        // Remove tasks from persistent storage.
3690        notifyTaskPersisterLocked(null, true);
3691    }
3692
3693    // Sort by taskId
3694    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3695        @Override
3696        public int compare(TaskRecord lhs, TaskRecord rhs) {
3697            return rhs.taskId - lhs.taskId;
3698        }
3699    };
3700
3701    // Extract the affiliates of the chain containing mRecentTasks[start].
3702    private int processNextAffiliateChainLocked(int start) {
3703        final TaskRecord startTask = mRecentTasks.get(start);
3704        final int affiliateId = startTask.mAffiliatedTaskId;
3705
3706        // Quick identification of isolated tasks. I.e. those not launched behind.
3707        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3708                startTask.mNextAffiliate == null) {
3709            // There is still a slim chance that there are other tasks that point to this task
3710            // and that the chain is so messed up that this task no longer points to them but
3711            // the gain of this optimization outweighs the risk.
3712            startTask.inRecents = true;
3713            return start + 1;
3714        }
3715
3716        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3717        mTmpRecents.clear();
3718        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3719            final TaskRecord task = mRecentTasks.get(i);
3720            if (task.mAffiliatedTaskId == affiliateId) {
3721                mRecentTasks.remove(i);
3722                mTmpRecents.add(task);
3723            }
3724        }
3725
3726        // Sort them all by taskId. That is the order they were create in and that order will
3727        // always be correct.
3728        Collections.sort(mTmpRecents, mTaskRecordComparator);
3729
3730        // Go through and fix up the linked list.
3731        // The first one is the end of the chain and has no next.
3732        final TaskRecord first = mTmpRecents.get(0);
3733        first.inRecents = true;
3734        if (first.mNextAffiliate != null) {
3735            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3736            first.setNextAffiliate(null);
3737            notifyTaskPersisterLocked(first, false);
3738        }
3739        // Everything in the middle is doubly linked from next to prev.
3740        final int tmpSize = mTmpRecents.size();
3741        for (int i = 0; i < tmpSize - 1; ++i) {
3742            final TaskRecord next = mTmpRecents.get(i);
3743            final TaskRecord prev = mTmpRecents.get(i + 1);
3744            if (next.mPrevAffiliate != prev) {
3745                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3746                        " setting prev=" + prev);
3747                next.setPrevAffiliate(prev);
3748                notifyTaskPersisterLocked(next, false);
3749            }
3750            if (prev.mNextAffiliate != next) {
3751                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3752                        " setting next=" + next);
3753                prev.setNextAffiliate(next);
3754                notifyTaskPersisterLocked(prev, false);
3755            }
3756            prev.inRecents = true;
3757        }
3758        // The last one is the beginning of the list and has no prev.
3759        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3760        if (last.mPrevAffiliate != null) {
3761            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3762            last.setPrevAffiliate(null);
3763            notifyTaskPersisterLocked(last, false);
3764        }
3765
3766        // Insert the group back into mRecentTasks at start.
3767        mRecentTasks.addAll(start, mTmpRecents);
3768
3769        // Let the caller know where we left off.
3770        return start + tmpSize;
3771    }
3772
3773    /**
3774     * Update the recent tasks lists: make sure tasks should still be here (their
3775     * applications / activities still exist), update their availability, fixup ordering
3776     * of affiliations.
3777     */
3778    void cleanupRecentTasksLocked(int userId) {
3779        if (mRecentTasks == null) {
3780            // Happens when called from the packagemanager broadcast before boot.
3781            return;
3782        }
3783
3784        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3785        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3786        final IPackageManager pm = AppGlobals.getPackageManager();
3787        final ActivityInfo dummyAct = new ActivityInfo();
3788        final ApplicationInfo dummyApp = new ApplicationInfo();
3789
3790        int N = mRecentTasks.size();
3791
3792        int[] users = userId == UserHandle.USER_ALL
3793                ? getUsersLocked() : new int[] { userId };
3794        for (int user : users) {
3795            for (int i = 0; i < N; i++) {
3796                TaskRecord task = mRecentTasks.get(i);
3797                if (task.userId != user) {
3798                    // Only look at tasks for the user ID of interest.
3799                    continue;
3800                }
3801                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3802                    // This situation is broken, and we should just get rid of it now.
3803                    mRecentTasks.remove(i);
3804                    task.removedFromRecents();
3805                    i--;
3806                    N--;
3807                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3808                    continue;
3809                }
3810                // Check whether this activity is currently available.
3811                if (task.realActivity != null) {
3812                    ActivityInfo ai = availActCache.get(task.realActivity);
3813                    if (ai == null) {
3814                        try {
3815                            ai = pm.getActivityInfo(task.realActivity,
3816                                    PackageManager.GET_UNINSTALLED_PACKAGES
3817                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3818                        } catch (RemoteException e) {
3819                            // Will never happen.
3820                            continue;
3821                        }
3822                        if (ai == null) {
3823                            ai = dummyAct;
3824                        }
3825                        availActCache.put(task.realActivity, ai);
3826                    }
3827                    if (ai == dummyAct) {
3828                        // This could be either because the activity no longer exists, or the
3829                        // app is temporarily gone.  For the former we want to remove the recents
3830                        // entry; for the latter we want to mark it as unavailable.
3831                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3832                        if (app == null) {
3833                            try {
3834                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3835                                        PackageManager.GET_UNINSTALLED_PACKAGES
3836                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3837                            } catch (RemoteException e) {
3838                                // Will never happen.
3839                                continue;
3840                            }
3841                            if (app == null) {
3842                                app = dummyApp;
3843                            }
3844                            availAppCache.put(task.realActivity.getPackageName(), app);
3845                        }
3846                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3847                            // Doesn't exist any more!  Good-bye.
3848                            mRecentTasks.remove(i);
3849                            task.removedFromRecents();
3850                            i--;
3851                            N--;
3852                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3853                            continue;
3854                        } else {
3855                            // Otherwise just not available for now.
3856                            if (task.isAvailable) {
3857                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3858                                        + task);
3859                            }
3860                            task.isAvailable = false;
3861                        }
3862                    } else {
3863                        if (!ai.enabled || !ai.applicationInfo.enabled
3864                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3865                            if (task.isAvailable) {
3866                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3867                                        + task + " (enabled=" + ai.enabled + "/"
3868                                        + ai.applicationInfo.enabled +  " flags="
3869                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3870                            }
3871                            task.isAvailable = false;
3872                        } else {
3873                            if (!task.isAvailable) {
3874                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3875                                        + task);
3876                            }
3877                            task.isAvailable = true;
3878                        }
3879                    }
3880                }
3881            }
3882        }
3883
3884        // Verify the affiliate chain for each task.
3885        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3886        }
3887
3888        mTmpRecents.clear();
3889        // mRecentTasks is now in sorted, affiliated order.
3890    }
3891
3892    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3893        int N = mRecentTasks.size();
3894        TaskRecord top = task;
3895        int topIndex = taskIndex;
3896        while (top.mNextAffiliate != null && topIndex > 0) {
3897            top = top.mNextAffiliate;
3898            topIndex--;
3899        }
3900        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3901                + topIndex + " from intial " + taskIndex);
3902        // Find the end of the chain, doing a sanity check along the way.
3903        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3904        int endIndex = topIndex;
3905        TaskRecord prev = top;
3906        while (endIndex < N) {
3907            TaskRecord cur = mRecentTasks.get(endIndex);
3908            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3909                    + endIndex + " " + cur);
3910            if (cur == top) {
3911                // Verify start of the chain.
3912                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3913                    Slog.wtf(TAG, "Bad chain @" + endIndex
3914                            + ": first task has next affiliate: " + prev);
3915                    sane = false;
3916                    break;
3917                }
3918            } else {
3919                // Verify middle of the chain's next points back to the one before.
3920                if (cur.mNextAffiliate != prev
3921                        || cur.mNextAffiliateTaskId != prev.taskId) {
3922                    Slog.wtf(TAG, "Bad chain @" + endIndex
3923                            + ": middle task " + cur + " @" + endIndex
3924                            + " has bad next affiliate "
3925                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3926                            + ", expected " + prev);
3927                    sane = false;
3928                    break;
3929                }
3930            }
3931            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3932                // Chain ends here.
3933                if (cur.mPrevAffiliate != null) {
3934                    Slog.wtf(TAG, "Bad chain @" + endIndex
3935                            + ": last task " + cur + " has previous affiliate "
3936                            + cur.mPrevAffiliate);
3937                    sane = false;
3938                }
3939                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3940                break;
3941            } else {
3942                // Verify middle of the chain's prev points to a valid item.
3943                if (cur.mPrevAffiliate == null) {
3944                    Slog.wtf(TAG, "Bad chain @" + endIndex
3945                            + ": task " + cur + " has previous affiliate "
3946                            + cur.mPrevAffiliate + " but should be id "
3947                            + cur.mPrevAffiliate);
3948                    sane = false;
3949                    break;
3950                }
3951            }
3952            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3953                Slog.wtf(TAG, "Bad chain @" + endIndex
3954                        + ": task " + cur + " has affiliated id "
3955                        + cur.mAffiliatedTaskId + " but should be "
3956                        + task.mAffiliatedTaskId);
3957                sane = false;
3958                break;
3959            }
3960            prev = cur;
3961            endIndex++;
3962            if (endIndex >= N) {
3963                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3964                        + ": last task " + prev);
3965                sane = false;
3966                break;
3967            }
3968        }
3969        if (sane) {
3970            if (endIndex < taskIndex) {
3971                Slog.wtf(TAG, "Bad chain @" + endIndex
3972                        + ": did not extend to task " + task + " @" + taskIndex);
3973                sane = false;
3974            }
3975        }
3976        if (sane) {
3977            // All looks good, we can just move all of the affiliated tasks
3978            // to the top.
3979            for (int i=topIndex; i<=endIndex; i++) {
3980                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3981                        + " from " + i + " to " + (i-topIndex));
3982                TaskRecord cur = mRecentTasks.remove(i);
3983                mRecentTasks.add(i-topIndex, cur);
3984            }
3985            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3986                    + " to " + endIndex);
3987            return true;
3988        }
3989
3990        // Whoops, couldn't do it.
3991        return false;
3992    }
3993
3994    final void addRecentTaskLocked(TaskRecord task) {
3995        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3996                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3997                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3998
3999        int N = mRecentTasks.size();
4000        // Quick case: check if the top-most recent task is the same.
4001        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4002            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4003            return;
4004        }
4005        // Another quick case: check if this is part of a set of affiliated
4006        // tasks that are at the top.
4007        if (isAffiliated && N > 0 && task.inRecents
4008                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4009            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4010                    + " at top when adding " + task);
4011            return;
4012        }
4013        // Another quick case: never add voice sessions.
4014        if (task.voiceSession != null) {
4015            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4016            return;
4017        }
4018
4019        boolean needAffiliationFix = false;
4020
4021        // Slightly less quick case: the task is already in recents, so all we need
4022        // to do is move it.
4023        if (task.inRecents) {
4024            int taskIndex = mRecentTasks.indexOf(task);
4025            if (taskIndex >= 0) {
4026                if (!isAffiliated) {
4027                    // Simple case: this is not an affiliated task, so we just move it to the front.
4028                    mRecentTasks.remove(taskIndex);
4029                    mRecentTasks.add(0, task);
4030                    notifyTaskPersisterLocked(task, false);
4031                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4032                            + " from " + taskIndex);
4033                    return;
4034                } else {
4035                    // More complicated: need to keep all affiliated tasks together.
4036                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4037                        // All went well.
4038                        return;
4039                    }
4040
4041                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4042                    // everything and then go through our general path of adding a new task.
4043                    needAffiliationFix = true;
4044                }
4045            } else {
4046                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4047                needAffiliationFix = true;
4048            }
4049        }
4050
4051        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4052        trimRecentsForTaskLocked(task, true);
4053
4054        N = mRecentTasks.size();
4055        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4056            final TaskRecord tr = mRecentTasks.remove(N - 1);
4057            tr.removedFromRecents();
4058            N--;
4059        }
4060        task.inRecents = true;
4061        if (!isAffiliated || needAffiliationFix) {
4062            // If this is a simple non-affiliated task, or we had some failure trying to
4063            // handle it as part of an affilated task, then just place it at the top.
4064            mRecentTasks.add(0, task);
4065        } else if (isAffiliated) {
4066            // If this is a new affiliated task, then move all of the affiliated tasks
4067            // to the front and insert this new one.
4068            TaskRecord other = task.mNextAffiliate;
4069            if (other == null) {
4070                other = task.mPrevAffiliate;
4071            }
4072            if (other != null) {
4073                int otherIndex = mRecentTasks.indexOf(other);
4074                if (otherIndex >= 0) {
4075                    // Insert new task at appropriate location.
4076                    int taskIndex;
4077                    if (other == task.mNextAffiliate) {
4078                        // We found the index of our next affiliation, which is who is
4079                        // before us in the list, so add after that point.
4080                        taskIndex = otherIndex+1;
4081                    } else {
4082                        // We found the index of our previous affiliation, which is who is
4083                        // after us in the list, so add at their position.
4084                        taskIndex = otherIndex;
4085                    }
4086                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4087                            + taskIndex + ": " + task);
4088                    mRecentTasks.add(taskIndex, task);
4089
4090                    // Now move everything to the front.
4091                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4092                        // All went well.
4093                        return;
4094                    }
4095
4096                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4097                    // everything and then go through our general path of adding a new task.
4098                    needAffiliationFix = true;
4099                } else {
4100                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4101                            + other);
4102                    needAffiliationFix = true;
4103                }
4104            } else {
4105                if (DEBUG_RECENTS) Slog.d(TAG,
4106                        "addRecent: adding affiliated task without next/prev:" + task);
4107                needAffiliationFix = true;
4108            }
4109        }
4110        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4111
4112        if (needAffiliationFix) {
4113            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4114            cleanupRecentTasksLocked(task.userId);
4115        }
4116    }
4117
4118    /**
4119     * If needed, remove oldest existing entries in recents that are for the same kind
4120     * of task as the given one.
4121     */
4122    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4123        int N = mRecentTasks.size();
4124        final Intent intent = task.intent;
4125        final boolean document = intent != null && intent.isDocument();
4126
4127        int maxRecents = task.maxRecents - 1;
4128        for (int i=0; i<N; i++) {
4129            final TaskRecord tr = mRecentTasks.get(i);
4130            if (task != tr) {
4131                if (task.userId != tr.userId) {
4132                    continue;
4133                }
4134                if (i > MAX_RECENT_BITMAPS) {
4135                    tr.freeLastThumbnail();
4136                }
4137                final Intent trIntent = tr.intent;
4138                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4139                    (intent == null || !intent.filterEquals(trIntent))) {
4140                    continue;
4141                }
4142                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4143                if (document && trIsDocument) {
4144                    // These are the same document activity (not necessarily the same doc).
4145                    if (maxRecents > 0) {
4146                        --maxRecents;
4147                        continue;
4148                    }
4149                    // Hit the maximum number of documents for this task. Fall through
4150                    // and remove this document from recents.
4151                } else if (document || trIsDocument) {
4152                    // Only one of these is a document. Not the droid we're looking for.
4153                    continue;
4154                }
4155            }
4156
4157            if (!doTrim) {
4158                // If the caller is not actually asking for a trim, just tell them we reached
4159                // a point where the trim would happen.
4160                return i;
4161            }
4162
4163            // Either task and tr are the same or, their affinities match or their intents match
4164            // and neither of them is a document, or they are documents using the same activity
4165            // and their maxRecents has been reached.
4166            tr.disposeThumbnail();
4167            mRecentTasks.remove(i);
4168            if (task != tr) {
4169                tr.removedFromRecents();
4170            }
4171            i--;
4172            N--;
4173            if (task.intent == null) {
4174                // If the new recent task we are adding is not fully
4175                // specified, then replace it with the existing recent task.
4176                task = tr;
4177            }
4178            notifyTaskPersisterLocked(tr, false);
4179        }
4180
4181        return -1;
4182    }
4183
4184    @Override
4185    public void reportActivityFullyDrawn(IBinder token) {
4186        synchronized (this) {
4187            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4188            if (r == null) {
4189                return;
4190            }
4191            r.reportFullyDrawnLocked();
4192        }
4193    }
4194
4195    @Override
4196    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4197        synchronized (this) {
4198            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4199            if (r == null) {
4200                return;
4201            }
4202            final long origId = Binder.clearCallingIdentity();
4203            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4204            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4205                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4206            if (config != null) {
4207                r.frozenBeforeDestroy = true;
4208                if (!updateConfigurationLocked(config, r, false, false)) {
4209                    mStackSupervisor.resumeTopActivitiesLocked();
4210                }
4211            }
4212            Binder.restoreCallingIdentity(origId);
4213        }
4214    }
4215
4216    @Override
4217    public int getRequestedOrientation(IBinder token) {
4218        synchronized (this) {
4219            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220            if (r == null) {
4221                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4222            }
4223            return mWindowManager.getAppOrientation(r.appToken);
4224        }
4225    }
4226
4227    /**
4228     * This is the internal entry point for handling Activity.finish().
4229     *
4230     * @param token The Binder token referencing the Activity we want to finish.
4231     * @param resultCode Result code, if any, from this Activity.
4232     * @param resultData Result data (Intent), if any, from this Activity.
4233     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4234     *            the root Activity in the task.
4235     *
4236     * @return Returns true if the activity successfully finished, or false if it is still running.
4237     */
4238    @Override
4239    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4240            boolean finishTask) {
4241        // Refuse possible leaked file descriptors
4242        if (resultData != null && resultData.hasFileDescriptors() == true) {
4243            throw new IllegalArgumentException("File descriptors passed in Intent");
4244        }
4245
4246        synchronized(this) {
4247            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4248            if (r == null) {
4249                return true;
4250            }
4251            // Keep track of the root activity of the task before we finish it
4252            TaskRecord tr = r.task;
4253            ActivityRecord rootR = tr.getRootActivity();
4254            if (rootR == null) {
4255                Slog.w(TAG, "Finishing task with all activities already finished");
4256            }
4257            // Do not allow task to finish in Lock Task mode.
4258            if (tr == mStackSupervisor.mLockTaskModeTask) {
4259                if (rootR == r) {
4260                    Slog.i(TAG, "Not finishing task in lock task mode");
4261                    mStackSupervisor.showLockTaskToast();
4262                    return false;
4263                }
4264            }
4265            if (mController != null) {
4266                // Find the first activity that is not finishing.
4267                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4268                if (next != null) {
4269                    // ask watcher if this is allowed
4270                    boolean resumeOK = true;
4271                    try {
4272                        resumeOK = mController.activityResuming(next.packageName);
4273                    } catch (RemoteException e) {
4274                        mController = null;
4275                        Watchdog.getInstance().setActivityController(null);
4276                    }
4277
4278                    if (!resumeOK) {
4279                        Slog.i(TAG, "Not finishing activity because controller resumed");
4280                        return false;
4281                    }
4282                }
4283            }
4284            final long origId = Binder.clearCallingIdentity();
4285            try {
4286                boolean res;
4287                if (finishTask && r == rootR) {
4288                    // If requested, remove the task that is associated to this activity only if it
4289                    // was the root activity in the task. The result code and data is ignored
4290                    // because we don't support returning them across task boundaries.
4291                    res = removeTaskByIdLocked(tr.taskId, false);
4292                    if (!res) {
4293                        Slog.i(TAG, "Removing task failed to finish activity");
4294                    }
4295                } else {
4296                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4297                            resultData, "app-request", true);
4298                    if (!res) {
4299                        Slog.i(TAG, "Failed to finish by app-request");
4300                    }
4301                }
4302                return res;
4303            } finally {
4304                Binder.restoreCallingIdentity(origId);
4305            }
4306        }
4307    }
4308
4309    @Override
4310    public final void finishHeavyWeightApp() {
4311        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4312                != PackageManager.PERMISSION_GRANTED) {
4313            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4314                    + Binder.getCallingPid()
4315                    + ", uid=" + Binder.getCallingUid()
4316                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4317            Slog.w(TAG, msg);
4318            throw new SecurityException(msg);
4319        }
4320
4321        synchronized(this) {
4322            if (mHeavyWeightProcess == null) {
4323                return;
4324            }
4325
4326            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4327                    mHeavyWeightProcess.activities);
4328            for (int i=0; i<activities.size(); i++) {
4329                ActivityRecord r = activities.get(i);
4330                if (!r.finishing) {
4331                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4332                            null, "finish-heavy", true);
4333                }
4334            }
4335
4336            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4337                    mHeavyWeightProcess.userId, 0));
4338            mHeavyWeightProcess = null;
4339        }
4340    }
4341
4342    @Override
4343    public void crashApplication(int uid, int initialPid, String packageName,
4344            String message) {
4345        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4346                != PackageManager.PERMISSION_GRANTED) {
4347            String msg = "Permission Denial: crashApplication() from pid="
4348                    + Binder.getCallingPid()
4349                    + ", uid=" + Binder.getCallingUid()
4350                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4351            Slog.w(TAG, msg);
4352            throw new SecurityException(msg);
4353        }
4354
4355        synchronized(this) {
4356            ProcessRecord proc = null;
4357
4358            // Figure out which process to kill.  We don't trust that initialPid
4359            // still has any relation to current pids, so must scan through the
4360            // list.
4361            synchronized (mPidsSelfLocked) {
4362                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4363                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4364                    if (p.uid != uid) {
4365                        continue;
4366                    }
4367                    if (p.pid == initialPid) {
4368                        proc = p;
4369                        break;
4370                    }
4371                    if (p.pkgList.containsKey(packageName)) {
4372                        proc = p;
4373                    }
4374                }
4375            }
4376
4377            if (proc == null) {
4378                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4379                        + " initialPid=" + initialPid
4380                        + " packageName=" + packageName);
4381                return;
4382            }
4383
4384            if (proc.thread != null) {
4385                if (proc.pid == Process.myPid()) {
4386                    Log.w(TAG, "crashApplication: trying to crash self!");
4387                    return;
4388                }
4389                long ident = Binder.clearCallingIdentity();
4390                try {
4391                    proc.thread.scheduleCrash(message);
4392                } catch (RemoteException e) {
4393                }
4394                Binder.restoreCallingIdentity(ident);
4395            }
4396        }
4397    }
4398
4399    @Override
4400    public final void finishSubActivity(IBinder token, String resultWho,
4401            int requestCode) {
4402        synchronized(this) {
4403            final long origId = Binder.clearCallingIdentity();
4404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4405            if (r != null) {
4406                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4407            }
4408            Binder.restoreCallingIdentity(origId);
4409        }
4410    }
4411
4412    @Override
4413    public boolean finishActivityAffinity(IBinder token) {
4414        synchronized(this) {
4415            final long origId = Binder.clearCallingIdentity();
4416            try {
4417                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4418
4419                ActivityRecord rootR = r.task.getRootActivity();
4420                // Do not allow task to finish in Lock Task mode.
4421                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4422                    if (rootR == r) {
4423                        mStackSupervisor.showLockTaskToast();
4424                        return false;
4425                    }
4426                }
4427                boolean res = false;
4428                if (r != null) {
4429                    res = r.task.stack.finishActivityAffinityLocked(r);
4430                }
4431                return res;
4432            } finally {
4433                Binder.restoreCallingIdentity(origId);
4434            }
4435        }
4436    }
4437
4438    @Override
4439    public void finishVoiceTask(IVoiceInteractionSession session) {
4440        synchronized(this) {
4441            final long origId = Binder.clearCallingIdentity();
4442            try {
4443                mStackSupervisor.finishVoiceTask(session);
4444            } finally {
4445                Binder.restoreCallingIdentity(origId);
4446            }
4447        }
4448
4449    }
4450
4451    @Override
4452    public boolean releaseActivityInstance(IBinder token) {
4453        synchronized(this) {
4454            final long origId = Binder.clearCallingIdentity();
4455            try {
4456                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4457                if (r.task == null || r.task.stack == null) {
4458                    return false;
4459                }
4460                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4461            } finally {
4462                Binder.restoreCallingIdentity(origId);
4463            }
4464        }
4465    }
4466
4467    @Override
4468    public void releaseSomeActivities(IApplicationThread appInt) {
4469        synchronized(this) {
4470            final long origId = Binder.clearCallingIdentity();
4471            try {
4472                ProcessRecord app = getRecordForAppLocked(appInt);
4473                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4474            } finally {
4475                Binder.restoreCallingIdentity(origId);
4476            }
4477        }
4478    }
4479
4480    @Override
4481    public boolean willActivityBeVisible(IBinder token) {
4482        synchronized(this) {
4483            ActivityStack stack = ActivityRecord.getStackLocked(token);
4484            if (stack != null) {
4485                return stack.willActivityBeVisibleLocked(token);
4486            }
4487            return false;
4488        }
4489    }
4490
4491    @Override
4492    public void overridePendingTransition(IBinder token, String packageName,
4493            int enterAnim, int exitAnim) {
4494        synchronized(this) {
4495            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4496            if (self == null) {
4497                return;
4498            }
4499
4500            final long origId = Binder.clearCallingIdentity();
4501
4502            if (self.state == ActivityState.RESUMED
4503                    || self.state == ActivityState.PAUSING) {
4504                mWindowManager.overridePendingAppTransition(packageName,
4505                        enterAnim, exitAnim, null);
4506            }
4507
4508            Binder.restoreCallingIdentity(origId);
4509        }
4510    }
4511
4512    /**
4513     * Main function for removing an existing process from the activity manager
4514     * as a result of that process going away.  Clears out all connections
4515     * to the process.
4516     */
4517    private final void handleAppDiedLocked(ProcessRecord app,
4518            boolean restarting, boolean allowRestart) {
4519        int pid = app.pid;
4520        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4521        if (!kept && !restarting) {
4522            removeLruProcessLocked(app);
4523            if (pid > 0) {
4524                ProcessList.remove(pid);
4525            }
4526        }
4527
4528        if (mProfileProc == app) {
4529            clearProfilerLocked();
4530        }
4531
4532        // Remove this application's activities from active lists.
4533        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4534
4535        app.activities.clear();
4536
4537        if (app.instrumentationClass != null) {
4538            Slog.w(TAG, "Crash of app " + app.processName
4539                  + " running instrumentation " + app.instrumentationClass);
4540            Bundle info = new Bundle();
4541            info.putString("shortMsg", "Process crashed.");
4542            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4543        }
4544
4545        if (!restarting) {
4546            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4547                // If there was nothing to resume, and we are not already
4548                // restarting this process, but there is a visible activity that
4549                // is hosted by the process...  then make sure all visible
4550                // activities are running, taking care of restarting this
4551                // process.
4552                if (hasVisibleActivities) {
4553                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4554                }
4555            }
4556        }
4557    }
4558
4559    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4560        IBinder threadBinder = thread.asBinder();
4561        // Find the application record.
4562        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4563            ProcessRecord rec = mLruProcesses.get(i);
4564            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4565                return i;
4566            }
4567        }
4568        return -1;
4569    }
4570
4571    final ProcessRecord getRecordForAppLocked(
4572            IApplicationThread thread) {
4573        if (thread == null) {
4574            return null;
4575        }
4576
4577        int appIndex = getLRURecordIndexForAppLocked(thread);
4578        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4579    }
4580
4581    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4582        // If there are no longer any background processes running,
4583        // and the app that died was not running instrumentation,
4584        // then tell everyone we are now low on memory.
4585        boolean haveBg = false;
4586        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4587            ProcessRecord rec = mLruProcesses.get(i);
4588            if (rec.thread != null
4589                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4590                haveBg = true;
4591                break;
4592            }
4593        }
4594
4595        if (!haveBg) {
4596            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4597            if (doReport) {
4598                long now = SystemClock.uptimeMillis();
4599                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4600                    doReport = false;
4601                } else {
4602                    mLastMemUsageReportTime = now;
4603                }
4604            }
4605            final ArrayList<ProcessMemInfo> memInfos
4606                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4607            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4608            long now = SystemClock.uptimeMillis();
4609            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4610                ProcessRecord rec = mLruProcesses.get(i);
4611                if (rec == dyingProc || rec.thread == null) {
4612                    continue;
4613                }
4614                if (doReport) {
4615                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4616                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4617                }
4618                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4619                    // The low memory report is overriding any current
4620                    // state for a GC request.  Make sure to do
4621                    // heavy/important/visible/foreground processes first.
4622                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4623                        rec.lastRequestedGc = 0;
4624                    } else {
4625                        rec.lastRequestedGc = rec.lastLowMemory;
4626                    }
4627                    rec.reportLowMemory = true;
4628                    rec.lastLowMemory = now;
4629                    mProcessesToGc.remove(rec);
4630                    addProcessToGcListLocked(rec);
4631                }
4632            }
4633            if (doReport) {
4634                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4635                mHandler.sendMessage(msg);
4636            }
4637            scheduleAppGcsLocked();
4638        }
4639    }
4640
4641    final void appDiedLocked(ProcessRecord app) {
4642       appDiedLocked(app, app.pid, app.thread);
4643    }
4644
4645    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4646        // First check if this ProcessRecord is actually active for the pid.
4647        synchronized (mPidsSelfLocked) {
4648            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4649            if (curProc != app) {
4650                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4651                return;
4652            }
4653        }
4654
4655        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4656        synchronized (stats) {
4657            stats.noteProcessDiedLocked(app.info.uid, pid);
4658        }
4659
4660        Process.killProcessQuiet(pid);
4661        Process.killProcessGroup(app.info.uid, pid);
4662        app.killed = true;
4663
4664        // Clean up already done if the process has been re-started.
4665        if (app.pid == pid && app.thread != null &&
4666                app.thread.asBinder() == thread.asBinder()) {
4667            boolean doLowMem = app.instrumentationClass == null;
4668            boolean doOomAdj = doLowMem;
4669            if (!app.killedByAm) {
4670                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4671                        + ") has died");
4672                mAllowLowerMemLevel = true;
4673            } else {
4674                // Note that we always want to do oom adj to update our state with the
4675                // new number of procs.
4676                mAllowLowerMemLevel = false;
4677                doLowMem = false;
4678            }
4679            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4680            if (DEBUG_CLEANUP) Slog.v(
4681                TAG, "Dying app: " + app + ", pid: " + pid
4682                + ", thread: " + thread.asBinder());
4683            handleAppDiedLocked(app, false, true);
4684
4685            if (doOomAdj) {
4686                updateOomAdjLocked();
4687            }
4688            if (doLowMem) {
4689                doLowMemReportIfNeededLocked(app);
4690            }
4691        } else if (app.pid != pid) {
4692            // A new process has already been started.
4693            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4694                    + ") has died and restarted (pid " + app.pid + ").");
4695            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4696        } else if (DEBUG_PROCESSES) {
4697            Slog.d(TAG, "Received spurious death notification for thread "
4698                    + thread.asBinder());
4699        }
4700    }
4701
4702    /**
4703     * If a stack trace dump file is configured, dump process stack traces.
4704     * @param clearTraces causes the dump file to be erased prior to the new
4705     *    traces being written, if true; when false, the new traces will be
4706     *    appended to any existing file content.
4707     * @param firstPids of dalvik VM processes to dump stack traces for first
4708     * @param lastPids of dalvik VM processes to dump stack traces for last
4709     * @param nativeProcs optional list of native process names to dump stack crawls
4710     * @return file containing stack traces, or null if no dump file is configured
4711     */
4712    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4713            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4714        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4715        if (tracesPath == null || tracesPath.length() == 0) {
4716            return null;
4717        }
4718
4719        File tracesFile = new File(tracesPath);
4720        try {
4721            File tracesDir = tracesFile.getParentFile();
4722            if (!tracesDir.exists()) {
4723                tracesDir.mkdirs();
4724                if (!SELinux.restorecon(tracesDir)) {
4725                    return null;
4726                }
4727            }
4728            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4729
4730            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4731            tracesFile.createNewFile();
4732            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4733        } catch (IOException e) {
4734            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4735            return null;
4736        }
4737
4738        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4739        return tracesFile;
4740    }
4741
4742    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4743            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4744        // Use a FileObserver to detect when traces finish writing.
4745        // The order of traces is considered important to maintain for legibility.
4746        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4747            @Override
4748            public synchronized void onEvent(int event, String path) { notify(); }
4749        };
4750
4751        try {
4752            observer.startWatching();
4753
4754            // First collect all of the stacks of the most important pids.
4755            if (firstPids != null) {
4756                try {
4757                    int num = firstPids.size();
4758                    for (int i = 0; i < num; i++) {
4759                        synchronized (observer) {
4760                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4761                            observer.wait(200);  // Wait for write-close, give up after 200msec
4762                        }
4763                    }
4764                } catch (InterruptedException e) {
4765                    Slog.wtf(TAG, e);
4766                }
4767            }
4768
4769            // Next collect the stacks of the native pids
4770            if (nativeProcs != null) {
4771                int[] pids = Process.getPidsForCommands(nativeProcs);
4772                if (pids != null) {
4773                    for (int pid : pids) {
4774                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4775                    }
4776                }
4777            }
4778
4779            // Lastly, measure CPU usage.
4780            if (processCpuTracker != null) {
4781                processCpuTracker.init();
4782                System.gc();
4783                processCpuTracker.update();
4784                try {
4785                    synchronized (processCpuTracker) {
4786                        processCpuTracker.wait(500); // measure over 1/2 second.
4787                    }
4788                } catch (InterruptedException e) {
4789                }
4790                processCpuTracker.update();
4791
4792                // We'll take the stack crawls of just the top apps using CPU.
4793                final int N = processCpuTracker.countWorkingStats();
4794                int numProcs = 0;
4795                for (int i=0; i<N && numProcs<5; i++) {
4796                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4797                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4798                        numProcs++;
4799                        try {
4800                            synchronized (observer) {
4801                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4802                                observer.wait(200);  // Wait for write-close, give up after 200msec
4803                            }
4804                        } catch (InterruptedException e) {
4805                            Slog.wtf(TAG, e);
4806                        }
4807
4808                    }
4809                }
4810            }
4811        } finally {
4812            observer.stopWatching();
4813        }
4814    }
4815
4816    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4817        if (true || IS_USER_BUILD) {
4818            return;
4819        }
4820        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4821        if (tracesPath == null || tracesPath.length() == 0) {
4822            return;
4823        }
4824
4825        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4826        StrictMode.allowThreadDiskWrites();
4827        try {
4828            final File tracesFile = new File(tracesPath);
4829            final File tracesDir = tracesFile.getParentFile();
4830            final File tracesTmp = new File(tracesDir, "__tmp__");
4831            try {
4832                if (!tracesDir.exists()) {
4833                    tracesDir.mkdirs();
4834                    if (!SELinux.restorecon(tracesDir.getPath())) {
4835                        return;
4836                    }
4837                }
4838                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4839
4840                if (tracesFile.exists()) {
4841                    tracesTmp.delete();
4842                    tracesFile.renameTo(tracesTmp);
4843                }
4844                StringBuilder sb = new StringBuilder();
4845                Time tobj = new Time();
4846                tobj.set(System.currentTimeMillis());
4847                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4848                sb.append(": ");
4849                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4850                sb.append(" since ");
4851                sb.append(msg);
4852                FileOutputStream fos = new FileOutputStream(tracesFile);
4853                fos.write(sb.toString().getBytes());
4854                if (app == null) {
4855                    fos.write("\n*** No application process!".getBytes());
4856                }
4857                fos.close();
4858                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4859            } catch (IOException e) {
4860                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4861                return;
4862            }
4863
4864            if (app != null) {
4865                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4866                firstPids.add(app.pid);
4867                dumpStackTraces(tracesPath, firstPids, null, null, null);
4868            }
4869
4870            File lastTracesFile = null;
4871            File curTracesFile = null;
4872            for (int i=9; i>=0; i--) {
4873                String name = String.format(Locale.US, "slow%02d.txt", i);
4874                curTracesFile = new File(tracesDir, name);
4875                if (curTracesFile.exists()) {
4876                    if (lastTracesFile != null) {
4877                        curTracesFile.renameTo(lastTracesFile);
4878                    } else {
4879                        curTracesFile.delete();
4880                    }
4881                }
4882                lastTracesFile = curTracesFile;
4883            }
4884            tracesFile.renameTo(curTracesFile);
4885            if (tracesTmp.exists()) {
4886                tracesTmp.renameTo(tracesFile);
4887            }
4888        } finally {
4889            StrictMode.setThreadPolicy(oldPolicy);
4890        }
4891    }
4892
4893    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4894            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4895        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4896        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4897
4898        if (mController != null) {
4899            try {
4900                // 0 == continue, -1 = kill process immediately
4901                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4902                if (res < 0 && app.pid != MY_PID) {
4903                    app.kill("anr", true);
4904                }
4905            } catch (RemoteException e) {
4906                mController = null;
4907                Watchdog.getInstance().setActivityController(null);
4908            }
4909        }
4910
4911        long anrTime = SystemClock.uptimeMillis();
4912        if (MONITOR_CPU_USAGE) {
4913            updateCpuStatsNow();
4914        }
4915
4916        synchronized (this) {
4917            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4918            if (mShuttingDown) {
4919                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.notResponding) {
4922                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4923                return;
4924            } else if (app.crashing) {
4925                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4926                return;
4927            }
4928
4929            // In case we come through here for the same app before completing
4930            // this one, mark as anring now so we will bail out.
4931            app.notResponding = true;
4932
4933            // Log the ANR to the event log.
4934            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4935                    app.processName, app.info.flags, annotation);
4936
4937            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4938            firstPids.add(app.pid);
4939
4940            int parentPid = app.pid;
4941            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4942            if (parentPid != app.pid) firstPids.add(parentPid);
4943
4944            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4945
4946            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4947                ProcessRecord r = mLruProcesses.get(i);
4948                if (r != null && r.thread != null) {
4949                    int pid = r.pid;
4950                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4951                        if (r.persistent) {
4952                            firstPids.add(pid);
4953                        } else {
4954                            lastPids.put(pid, Boolean.TRUE);
4955                        }
4956                    }
4957                }
4958            }
4959        }
4960
4961        // Log the ANR to the main log.
4962        StringBuilder info = new StringBuilder();
4963        info.setLength(0);
4964        info.append("ANR in ").append(app.processName);
4965        if (activity != null && activity.shortComponentName != null) {
4966            info.append(" (").append(activity.shortComponentName).append(")");
4967        }
4968        info.append("\n");
4969        info.append("PID: ").append(app.pid).append("\n");
4970        if (annotation != null) {
4971            info.append("Reason: ").append(annotation).append("\n");
4972        }
4973        if (parent != null && parent != activity) {
4974            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4975        }
4976
4977        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4978
4979        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4980                NATIVE_STACKS_OF_INTEREST);
4981
4982        String cpuInfo = null;
4983        if (MONITOR_CPU_USAGE) {
4984            updateCpuStatsNow();
4985            synchronized (mProcessCpuTracker) {
4986                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4987            }
4988            info.append(processCpuTracker.printCurrentLoad());
4989            info.append(cpuInfo);
4990        }
4991
4992        info.append(processCpuTracker.printCurrentState(anrTime));
4993
4994        Slog.e(TAG, info.toString());
4995        if (tracesFile == null) {
4996            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4997            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4998        }
4999
5000        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5001                cpuInfo, tracesFile, null);
5002
5003        if (mController != null) {
5004            try {
5005                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5006                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5007                if (res != 0) {
5008                    if (res < 0 && app.pid != MY_PID) {
5009                        app.kill("anr", true);
5010                    } else {
5011                        synchronized (this) {
5012                            mServices.scheduleServiceTimeoutLocked(app);
5013                        }
5014                    }
5015                    return;
5016                }
5017            } catch (RemoteException e) {
5018                mController = null;
5019                Watchdog.getInstance().setActivityController(null);
5020            }
5021        }
5022
5023        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5024        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5025                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5026
5027        synchronized (this) {
5028            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5029
5030            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5031                app.kill("bg anr", true);
5032                return;
5033            }
5034
5035            // Set the app's notResponding state, and look up the errorReportReceiver
5036            makeAppNotRespondingLocked(app,
5037                    activity != null ? activity.shortComponentName : null,
5038                    annotation != null ? "ANR " + annotation : "ANR",
5039                    info.toString());
5040
5041            // Bring up the infamous App Not Responding dialog
5042            Message msg = Message.obtain();
5043            HashMap<String, Object> map = new HashMap<String, Object>();
5044            msg.what = SHOW_NOT_RESPONDING_MSG;
5045            msg.obj = map;
5046            msg.arg1 = aboveSystem ? 1 : 0;
5047            map.put("app", app);
5048            if (activity != null) {
5049                map.put("activity", activity);
5050            }
5051
5052            mHandler.sendMessage(msg);
5053        }
5054    }
5055
5056    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5057        if (!mLaunchWarningShown) {
5058            mLaunchWarningShown = true;
5059            mHandler.post(new Runnable() {
5060                @Override
5061                public void run() {
5062                    synchronized (ActivityManagerService.this) {
5063                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5064                        d.show();
5065                        mHandler.postDelayed(new Runnable() {
5066                            @Override
5067                            public void run() {
5068                                synchronized (ActivityManagerService.this) {
5069                                    d.dismiss();
5070                                    mLaunchWarningShown = false;
5071                                }
5072                            }
5073                        }, 4000);
5074                    }
5075                }
5076            });
5077        }
5078    }
5079
5080    @Override
5081    public boolean clearApplicationUserData(final String packageName,
5082            final IPackageDataObserver observer, int userId) {
5083        enforceNotIsolatedCaller("clearApplicationUserData");
5084        int uid = Binder.getCallingUid();
5085        int pid = Binder.getCallingPid();
5086        userId = handleIncomingUser(pid, uid,
5087                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5088        long callingId = Binder.clearCallingIdentity();
5089        try {
5090            IPackageManager pm = AppGlobals.getPackageManager();
5091            int pkgUid = -1;
5092            synchronized(this) {
5093                try {
5094                    pkgUid = pm.getPackageUid(packageName, userId);
5095                } catch (RemoteException e) {
5096                }
5097                if (pkgUid == -1) {
5098                    Slog.w(TAG, "Invalid packageName: " + packageName);
5099                    if (observer != null) {
5100                        try {
5101                            observer.onRemoveCompleted(packageName, false);
5102                        } catch (RemoteException e) {
5103                            Slog.i(TAG, "Observer no longer exists.");
5104                        }
5105                    }
5106                    return false;
5107                }
5108                if (uid == pkgUid || checkComponentPermission(
5109                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5110                        pid, uid, -1, true)
5111                        == PackageManager.PERMISSION_GRANTED) {
5112                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5113                } else {
5114                    throw new SecurityException("PID " + pid + " does not have permission "
5115                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5116                                    + " of package " + packageName);
5117                }
5118
5119                // Remove all tasks match the cleared application package and user
5120                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5121                    final TaskRecord tr = mRecentTasks.get(i);
5122                    final String taskPackageName =
5123                            tr.getBaseIntent().getComponent().getPackageName();
5124                    if (tr.userId != userId) continue;
5125                    if (!taskPackageName.equals(packageName)) continue;
5126                    removeTaskByIdLocked(tr.taskId, false);
5127                }
5128            }
5129
5130            try {
5131                // Clear application user data
5132                pm.clearApplicationUserData(packageName, observer, userId);
5133
5134                synchronized(this) {
5135                    // Remove all permissions granted from/to this package
5136                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5137                }
5138
5139                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5140                        Uri.fromParts("package", packageName, null));
5141                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5142                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5143                        null, null, 0, null, null, null, false, false, userId);
5144            } catch (RemoteException e) {
5145            }
5146        } finally {
5147            Binder.restoreCallingIdentity(callingId);
5148        }
5149        return true;
5150    }
5151
5152    @Override
5153    public void killBackgroundProcesses(final String packageName, int userId) {
5154        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5155                != PackageManager.PERMISSION_GRANTED &&
5156                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5157                        != PackageManager.PERMISSION_GRANTED) {
5158            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5159                    + Binder.getCallingPid()
5160                    + ", uid=" + Binder.getCallingUid()
5161                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5162            Slog.w(TAG, msg);
5163            throw new SecurityException(msg);
5164        }
5165
5166        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5167                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5168        long callingId = Binder.clearCallingIdentity();
5169        try {
5170            IPackageManager pm = AppGlobals.getPackageManager();
5171            synchronized(this) {
5172                int appId = -1;
5173                try {
5174                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5175                } catch (RemoteException e) {
5176                }
5177                if (appId == -1) {
5178                    Slog.w(TAG, "Invalid packageName: " + packageName);
5179                    return;
5180                }
5181                killPackageProcessesLocked(packageName, appId, userId,
5182                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5183            }
5184        } finally {
5185            Binder.restoreCallingIdentity(callingId);
5186        }
5187    }
5188
5189    @Override
5190    public void killAllBackgroundProcesses() {
5191        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5192                != PackageManager.PERMISSION_GRANTED) {
5193            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5194                    + Binder.getCallingPid()
5195                    + ", uid=" + Binder.getCallingUid()
5196                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197            Slog.w(TAG, msg);
5198            throw new SecurityException(msg);
5199        }
5200
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            synchronized(this) {
5204                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5205                final int NP = mProcessNames.getMap().size();
5206                for (int ip=0; ip<NP; ip++) {
5207                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5208                    final int NA = apps.size();
5209                    for (int ia=0; ia<NA; ia++) {
5210                        ProcessRecord app = apps.valueAt(ia);
5211                        if (app.persistent) {
5212                            // we don't kill persistent processes
5213                            continue;
5214                        }
5215                        if (app.removed) {
5216                            procs.add(app);
5217                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5218                            app.removed = true;
5219                            procs.add(app);
5220                        }
5221                    }
5222                }
5223
5224                int N = procs.size();
5225                for (int i=0; i<N; i++) {
5226                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5227                }
5228                mAllowLowerMemLevel = true;
5229                updateOomAdjLocked();
5230                doLowMemReportIfNeededLocked(null);
5231            }
5232        } finally {
5233            Binder.restoreCallingIdentity(callingId);
5234        }
5235    }
5236
5237    @Override
5238    public void forceStopPackage(final String packageName, int userId) {
5239        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5240                != PackageManager.PERMISSION_GRANTED) {
5241            String msg = "Permission Denial: forceStopPackage() from pid="
5242                    + Binder.getCallingPid()
5243                    + ", uid=" + Binder.getCallingUid()
5244                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5245            Slog.w(TAG, msg);
5246            throw new SecurityException(msg);
5247        }
5248        final int callingPid = Binder.getCallingPid();
5249        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5250                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5251        long callingId = Binder.clearCallingIdentity();
5252        try {
5253            IPackageManager pm = AppGlobals.getPackageManager();
5254            synchronized(this) {
5255                int[] users = userId == UserHandle.USER_ALL
5256                        ? getUsersLocked() : new int[] { userId };
5257                for (int user : users) {
5258                    int pkgUid = -1;
5259                    try {
5260                        pkgUid = pm.getPackageUid(packageName, user);
5261                    } catch (RemoteException e) {
5262                    }
5263                    if (pkgUid == -1) {
5264                        Slog.w(TAG, "Invalid packageName: " + packageName);
5265                        continue;
5266                    }
5267                    try {
5268                        pm.setPackageStoppedState(packageName, true, user);
5269                    } catch (RemoteException e) {
5270                    } catch (IllegalArgumentException e) {
5271                        Slog.w(TAG, "Failed trying to unstop package "
5272                                + packageName + ": " + e);
5273                    }
5274                    if (isUserRunningLocked(user, false)) {
5275                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5276                    }
5277                }
5278            }
5279        } finally {
5280            Binder.restoreCallingIdentity(callingId);
5281        }
5282    }
5283
5284    @Override
5285    public void addPackageDependency(String packageName) {
5286        synchronized (this) {
5287            int callingPid = Binder.getCallingPid();
5288            if (callingPid == Process.myPid()) {
5289                //  Yeah, um, no.
5290                Slog.w(TAG, "Can't addPackageDependency on system process");
5291                return;
5292            }
5293            ProcessRecord proc;
5294            synchronized (mPidsSelfLocked) {
5295                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5296            }
5297            if (proc != null) {
5298                if (proc.pkgDeps == null) {
5299                    proc.pkgDeps = new ArraySet<String>(1);
5300                }
5301                proc.pkgDeps.add(packageName);
5302            }
5303        }
5304    }
5305
5306    /*
5307     * The pkg name and app id have to be specified.
5308     */
5309    @Override
5310    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5311        if (pkg == null) {
5312            return;
5313        }
5314        // Make sure the uid is valid.
5315        if (appid < 0) {
5316            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5317            return;
5318        }
5319        int callerUid = Binder.getCallingUid();
5320        // Only the system server can kill an application
5321        if (callerUid == Process.SYSTEM_UID) {
5322            // Post an aysnc message to kill the application
5323            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5324            msg.arg1 = appid;
5325            msg.arg2 = 0;
5326            Bundle bundle = new Bundle();
5327            bundle.putString("pkg", pkg);
5328            bundle.putString("reason", reason);
5329            msg.obj = bundle;
5330            mHandler.sendMessage(msg);
5331        } else {
5332            throw new SecurityException(callerUid + " cannot kill pkg: " +
5333                    pkg);
5334        }
5335    }
5336
5337    @Override
5338    public void closeSystemDialogs(String reason) {
5339        enforceNotIsolatedCaller("closeSystemDialogs");
5340
5341        final int pid = Binder.getCallingPid();
5342        final int uid = Binder.getCallingUid();
5343        final long origId = Binder.clearCallingIdentity();
5344        try {
5345            synchronized (this) {
5346                // Only allow this from foreground processes, so that background
5347                // applications can't abuse it to prevent system UI from being shown.
5348                if (uid >= Process.FIRST_APPLICATION_UID) {
5349                    ProcessRecord proc;
5350                    synchronized (mPidsSelfLocked) {
5351                        proc = mPidsSelfLocked.get(pid);
5352                    }
5353                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5354                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5355                                + " from background process " + proc);
5356                        return;
5357                    }
5358                }
5359                closeSystemDialogsLocked(reason);
5360            }
5361        } finally {
5362            Binder.restoreCallingIdentity(origId);
5363        }
5364    }
5365
5366    void closeSystemDialogsLocked(String reason) {
5367        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5368        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5369                | Intent.FLAG_RECEIVER_FOREGROUND);
5370        if (reason != null) {
5371            intent.putExtra("reason", reason);
5372        }
5373        mWindowManager.closeSystemDialogs(reason);
5374
5375        mStackSupervisor.closeSystemDialogsLocked();
5376
5377        broadcastIntentLocked(null, null, intent, null,
5378                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5379                Process.SYSTEM_UID, UserHandle.USER_ALL);
5380    }
5381
5382    @Override
5383    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5384        enforceNotIsolatedCaller("getProcessMemoryInfo");
5385        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5386        for (int i=pids.length-1; i>=0; i--) {
5387            ProcessRecord proc;
5388            int oomAdj;
5389            synchronized (this) {
5390                synchronized (mPidsSelfLocked) {
5391                    proc = mPidsSelfLocked.get(pids[i]);
5392                    oomAdj = proc != null ? proc.setAdj : 0;
5393                }
5394            }
5395            infos[i] = new Debug.MemoryInfo();
5396            Debug.getMemoryInfo(pids[i], infos[i]);
5397            if (proc != null) {
5398                synchronized (this) {
5399                    if (proc.thread != null && proc.setAdj == oomAdj) {
5400                        // Record this for posterity if the process has been stable.
5401                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5402                                infos[i].getTotalUss(), false, proc.pkgList);
5403                    }
5404                }
5405            }
5406        }
5407        return infos;
5408    }
5409
5410    @Override
5411    public long[] getProcessPss(int[] pids) {
5412        enforceNotIsolatedCaller("getProcessPss");
5413        long[] pss = new long[pids.length];
5414        for (int i=pids.length-1; i>=0; i--) {
5415            ProcessRecord proc;
5416            int oomAdj;
5417            synchronized (this) {
5418                synchronized (mPidsSelfLocked) {
5419                    proc = mPidsSelfLocked.get(pids[i]);
5420                    oomAdj = proc != null ? proc.setAdj : 0;
5421                }
5422            }
5423            long[] tmpUss = new long[1];
5424            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5425            if (proc != null) {
5426                synchronized (this) {
5427                    if (proc.thread != null && proc.setAdj == oomAdj) {
5428                        // Record this for posterity if the process has been stable.
5429                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5430                    }
5431                }
5432            }
5433        }
5434        return pss;
5435    }
5436
5437    @Override
5438    public void killApplicationProcess(String processName, int uid) {
5439        if (processName == null) {
5440            return;
5441        }
5442
5443        int callerUid = Binder.getCallingUid();
5444        // Only the system server can kill an application
5445        if (callerUid == Process.SYSTEM_UID) {
5446            synchronized (this) {
5447                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5448                if (app != null && app.thread != null) {
5449                    try {
5450                        app.thread.scheduleSuicide();
5451                    } catch (RemoteException e) {
5452                        // If the other end already died, then our work here is done.
5453                    }
5454                } else {
5455                    Slog.w(TAG, "Process/uid not found attempting kill of "
5456                            + processName + " / " + uid);
5457                }
5458            }
5459        } else {
5460            throw new SecurityException(callerUid + " cannot kill app process: " +
5461                    processName);
5462        }
5463    }
5464
5465    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5466        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5467                false, true, false, false, UserHandle.getUserId(uid), reason);
5468        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5469                Uri.fromParts("package", packageName, null));
5470        if (!mProcessesReady) {
5471            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5472                    | Intent.FLAG_RECEIVER_FOREGROUND);
5473        }
5474        intent.putExtra(Intent.EXTRA_UID, uid);
5475        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5476        broadcastIntentLocked(null, null, intent,
5477                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5478                false, false,
5479                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5480    }
5481
5482    private void forceStopUserLocked(int userId, String reason) {
5483        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5484        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5485        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5486                | Intent.FLAG_RECEIVER_FOREGROUND);
5487        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5488        broadcastIntentLocked(null, null, intent,
5489                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5490                false, false,
5491                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5492    }
5493
5494    private final boolean killPackageProcessesLocked(String packageName, int appId,
5495            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5496            boolean doit, boolean evenPersistent, String reason) {
5497        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5498
5499        // Remove all processes this package may have touched: all with the
5500        // same UID (except for the system or root user), and all whose name
5501        // matches the package name.
5502        final int NP = mProcessNames.getMap().size();
5503        for (int ip=0; ip<NP; ip++) {
5504            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5505            final int NA = apps.size();
5506            for (int ia=0; ia<NA; ia++) {
5507                ProcessRecord app = apps.valueAt(ia);
5508                if (app.persistent && !evenPersistent) {
5509                    // we don't kill persistent processes
5510                    continue;
5511                }
5512                if (app.removed) {
5513                    if (doit) {
5514                        procs.add(app);
5515                    }
5516                    continue;
5517                }
5518
5519                // Skip process if it doesn't meet our oom adj requirement.
5520                if (app.setAdj < minOomAdj) {
5521                    continue;
5522                }
5523
5524                // If no package is specified, we call all processes under the
5525                // give user id.
5526                if (packageName == null) {
5527                    if (app.userId != userId) {
5528                        continue;
5529                    }
5530                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5531                        continue;
5532                    }
5533                // Package has been specified, we want to hit all processes
5534                // that match it.  We need to qualify this by the processes
5535                // that are running under the specified app and user ID.
5536                } else {
5537                    final boolean isDep = app.pkgDeps != null
5538                            && app.pkgDeps.contains(packageName);
5539                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5540                        continue;
5541                    }
5542                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5543                        continue;
5544                    }
5545                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5546                        continue;
5547                    }
5548                }
5549
5550                // Process has passed all conditions, kill it!
5551                if (!doit) {
5552                    return true;
5553                }
5554                app.removed = true;
5555                procs.add(app);
5556            }
5557        }
5558
5559        int N = procs.size();
5560        for (int i=0; i<N; i++) {
5561            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5562        }
5563        updateOomAdjLocked();
5564        return N > 0;
5565    }
5566
5567    private final boolean forceStopPackageLocked(String name, int appId,
5568            boolean callerWillRestart, boolean purgeCache, boolean doit,
5569            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5570        int i;
5571        int N;
5572
5573        if (userId == UserHandle.USER_ALL && name == null) {
5574            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5575        }
5576
5577        if (appId < 0 && name != null) {
5578            try {
5579                appId = UserHandle.getAppId(
5580                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5581            } catch (RemoteException e) {
5582            }
5583        }
5584
5585        if (doit) {
5586            if (name != null) {
5587                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5588                        + " user=" + userId + ": " + reason);
5589            } else {
5590                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5591            }
5592
5593            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5594            for (int ip=pmap.size()-1; ip>=0; ip--) {
5595                SparseArray<Long> ba = pmap.valueAt(ip);
5596                for (i=ba.size()-1; i>=0; i--) {
5597                    boolean remove = false;
5598                    final int entUid = ba.keyAt(i);
5599                    if (name != null) {
5600                        if (userId == UserHandle.USER_ALL) {
5601                            if (UserHandle.getAppId(entUid) == appId) {
5602                                remove = true;
5603                            }
5604                        } else {
5605                            if (entUid == UserHandle.getUid(userId, appId)) {
5606                                remove = true;
5607                            }
5608                        }
5609                    } else if (UserHandle.getUserId(entUid) == userId) {
5610                        remove = true;
5611                    }
5612                    if (remove) {
5613                        ba.removeAt(i);
5614                    }
5615                }
5616                if (ba.size() == 0) {
5617                    pmap.removeAt(ip);
5618                }
5619            }
5620        }
5621
5622        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5623                -100, callerWillRestart, true, doit, evenPersistent,
5624                name == null ? ("stop user " + userId) : ("stop " + name));
5625
5626        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5627            if (!doit) {
5628                return true;
5629            }
5630            didSomething = true;
5631        }
5632
5633        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5634            if (!doit) {
5635                return true;
5636            }
5637            didSomething = true;
5638        }
5639
5640        if (name == null) {
5641            // Remove all sticky broadcasts from this user.
5642            mStickyBroadcasts.remove(userId);
5643        }
5644
5645        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5646        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5647                userId, providers)) {
5648            if (!doit) {
5649                return true;
5650            }
5651            didSomething = true;
5652        }
5653        N = providers.size();
5654        for (i=0; i<N; i++) {
5655            removeDyingProviderLocked(null, providers.get(i), true);
5656        }
5657
5658        // Remove transient permissions granted from/to this package/user
5659        removeUriPermissionsForPackageLocked(name, userId, false);
5660
5661        if (name == null || uninstalling) {
5662            // Remove pending intents.  For now we only do this when force
5663            // stopping users, because we have some problems when doing this
5664            // for packages -- app widgets are not currently cleaned up for
5665            // such packages, so they can be left with bad pending intents.
5666            if (mIntentSenderRecords.size() > 0) {
5667                Iterator<WeakReference<PendingIntentRecord>> it
5668                        = mIntentSenderRecords.values().iterator();
5669                while (it.hasNext()) {
5670                    WeakReference<PendingIntentRecord> wpir = it.next();
5671                    if (wpir == null) {
5672                        it.remove();
5673                        continue;
5674                    }
5675                    PendingIntentRecord pir = wpir.get();
5676                    if (pir == null) {
5677                        it.remove();
5678                        continue;
5679                    }
5680                    if (name == null) {
5681                        // Stopping user, remove all objects for the user.
5682                        if (pir.key.userId != userId) {
5683                            // Not the same user, skip it.
5684                            continue;
5685                        }
5686                    } else {
5687                        if (UserHandle.getAppId(pir.uid) != appId) {
5688                            // Different app id, skip it.
5689                            continue;
5690                        }
5691                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5692                            // Different user, skip it.
5693                            continue;
5694                        }
5695                        if (!pir.key.packageName.equals(name)) {
5696                            // Different package, skip it.
5697                            continue;
5698                        }
5699                    }
5700                    if (!doit) {
5701                        return true;
5702                    }
5703                    didSomething = true;
5704                    it.remove();
5705                    pir.canceled = true;
5706                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5707                        pir.key.activity.pendingResults.remove(pir.ref);
5708                    }
5709                }
5710            }
5711        }
5712
5713        if (doit) {
5714            if (purgeCache && name != null) {
5715                AttributeCache ac = AttributeCache.instance();
5716                if (ac != null) {
5717                    ac.removePackage(name);
5718                }
5719            }
5720            if (mBooted) {
5721                mStackSupervisor.resumeTopActivitiesLocked();
5722                mStackSupervisor.scheduleIdleLocked();
5723            }
5724        }
5725
5726        return didSomething;
5727    }
5728
5729    private final boolean removeProcessLocked(ProcessRecord app,
5730            boolean callerWillRestart, boolean allowRestart, String reason) {
5731        final String name = app.processName;
5732        final int uid = app.uid;
5733        if (DEBUG_PROCESSES) Slog.d(
5734            TAG, "Force removing proc " + app.toShortString() + " (" + name
5735            + "/" + uid + ")");
5736
5737        mProcessNames.remove(name, uid);
5738        mIsolatedProcesses.remove(app.uid);
5739        if (mHeavyWeightProcess == app) {
5740            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5741                    mHeavyWeightProcess.userId, 0));
5742            mHeavyWeightProcess = null;
5743        }
5744        boolean needRestart = false;
5745        if (app.pid > 0 && app.pid != MY_PID) {
5746            int pid = app.pid;
5747            synchronized (mPidsSelfLocked) {
5748                mPidsSelfLocked.remove(pid);
5749                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5750            }
5751            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5752            if (app.isolated) {
5753                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5754            }
5755            app.kill(reason, true);
5756            handleAppDiedLocked(app, true, allowRestart);
5757            removeLruProcessLocked(app);
5758
5759            if (app.persistent && !app.isolated) {
5760                if (!callerWillRestart) {
5761                    addAppLocked(app.info, false, null /* ABI override */);
5762                } else {
5763                    needRestart = true;
5764                }
5765            }
5766        } else {
5767            mRemovedProcesses.add(app);
5768        }
5769
5770        return needRestart;
5771    }
5772
5773    private final void processStartTimedOutLocked(ProcessRecord app) {
5774        final int pid = app.pid;
5775        boolean gone = false;
5776        synchronized (mPidsSelfLocked) {
5777            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5778            if (knownApp != null && knownApp.thread == null) {
5779                mPidsSelfLocked.remove(pid);
5780                gone = true;
5781            }
5782        }
5783
5784        if (gone) {
5785            Slog.w(TAG, "Process " + app + " failed to attach");
5786            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5787                    pid, app.uid, app.processName);
5788            mProcessNames.remove(app.processName, app.uid);
5789            mIsolatedProcesses.remove(app.uid);
5790            if (mHeavyWeightProcess == app) {
5791                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5792                        mHeavyWeightProcess.userId, 0));
5793                mHeavyWeightProcess = null;
5794            }
5795            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5796            if (app.isolated) {
5797                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5798            }
5799            // Take care of any launching providers waiting for this process.
5800            checkAppInLaunchingProvidersLocked(app, true);
5801            // Take care of any services that are waiting for the process.
5802            mServices.processStartTimedOutLocked(app);
5803            app.kill("start timeout", true);
5804            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5805                Slog.w(TAG, "Unattached app died before backup, skipping");
5806                try {
5807                    IBackupManager bm = IBackupManager.Stub.asInterface(
5808                            ServiceManager.getService(Context.BACKUP_SERVICE));
5809                    bm.agentDisconnected(app.info.packageName);
5810                } catch (RemoteException e) {
5811                    // Can't happen; the backup manager is local
5812                }
5813            }
5814            if (isPendingBroadcastProcessLocked(pid)) {
5815                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5816                skipPendingBroadcastLocked(pid);
5817            }
5818        } else {
5819            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5820        }
5821    }
5822
5823    private final boolean attachApplicationLocked(IApplicationThread thread,
5824            int pid) {
5825
5826        // Find the application record that is being attached...  either via
5827        // the pid if we are running in multiple processes, or just pull the
5828        // next app record if we are emulating process with anonymous threads.
5829        ProcessRecord app;
5830        if (pid != MY_PID && pid >= 0) {
5831            synchronized (mPidsSelfLocked) {
5832                app = mPidsSelfLocked.get(pid);
5833            }
5834        } else {
5835            app = null;
5836        }
5837
5838        if (app == null) {
5839            Slog.w(TAG, "No pending application record for pid " + pid
5840                    + " (IApplicationThread " + thread + "); dropping process");
5841            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5842            if (pid > 0 && pid != MY_PID) {
5843                Process.killProcessQuiet(pid);
5844                //TODO: Process.killProcessGroup(app.info.uid, pid);
5845            } else {
5846                try {
5847                    thread.scheduleExit();
5848                } catch (Exception e) {
5849                    // Ignore exceptions.
5850                }
5851            }
5852            return false;
5853        }
5854
5855        // If this application record is still attached to a previous
5856        // process, clean it up now.
5857        if (app.thread != null) {
5858            handleAppDiedLocked(app, true, true);
5859        }
5860
5861        // Tell the process all about itself.
5862
5863        if (localLOGV) Slog.v(
5864                TAG, "Binding process pid " + pid + " to record " + app);
5865
5866        final String processName = app.processName;
5867        try {
5868            AppDeathRecipient adr = new AppDeathRecipient(
5869                    app, pid, thread);
5870            thread.asBinder().linkToDeath(adr, 0);
5871            app.deathRecipient = adr;
5872        } catch (RemoteException e) {
5873            app.resetPackageList(mProcessStats);
5874            startProcessLocked(app, "link fail", processName);
5875            return false;
5876        }
5877
5878        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5879
5880        app.makeActive(thread, mProcessStats);
5881        app.curAdj = app.setAdj = -100;
5882        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5883        app.forcingToForeground = null;
5884        updateProcessForegroundLocked(app, false, false);
5885        app.hasShownUi = false;
5886        app.debugging = false;
5887        app.cached = false;
5888        app.killedByAm = false;
5889
5890        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5891
5892        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5893        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5894
5895        if (!normalMode) {
5896            Slog.i(TAG, "Launching preboot mode app: " + app);
5897        }
5898
5899        if (localLOGV) Slog.v(
5900            TAG, "New app record " + app
5901            + " thread=" + thread.asBinder() + " pid=" + pid);
5902        try {
5903            int testMode = IApplicationThread.DEBUG_OFF;
5904            if (mDebugApp != null && mDebugApp.equals(processName)) {
5905                testMode = mWaitForDebugger
5906                    ? IApplicationThread.DEBUG_WAIT
5907                    : IApplicationThread.DEBUG_ON;
5908                app.debugging = true;
5909                if (mDebugTransient) {
5910                    mDebugApp = mOrigDebugApp;
5911                    mWaitForDebugger = mOrigWaitForDebugger;
5912                }
5913            }
5914            String profileFile = app.instrumentationProfileFile;
5915            ParcelFileDescriptor profileFd = null;
5916            int samplingInterval = 0;
5917            boolean profileAutoStop = false;
5918            if (mProfileApp != null && mProfileApp.equals(processName)) {
5919                mProfileProc = app;
5920                profileFile = mProfileFile;
5921                profileFd = mProfileFd;
5922                samplingInterval = mSamplingInterval;
5923                profileAutoStop = mAutoStopProfiler;
5924            }
5925            boolean enableOpenGlTrace = false;
5926            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5927                enableOpenGlTrace = true;
5928                mOpenGlTraceApp = null;
5929            }
5930
5931            // If the app is being launched for restore or full backup, set it up specially
5932            boolean isRestrictedBackupMode = false;
5933            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5934                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5935                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5936                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5937            }
5938
5939            ensurePackageDexOpt(app.instrumentationInfo != null
5940                    ? app.instrumentationInfo.packageName
5941                    : app.info.packageName);
5942            if (app.instrumentationClass != null) {
5943                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5944            }
5945            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5946                    + processName + " with config " + mConfiguration);
5947            ApplicationInfo appInfo = app.instrumentationInfo != null
5948                    ? app.instrumentationInfo : app.info;
5949            app.compat = compatibilityInfoForPackageLocked(appInfo);
5950            if (profileFd != null) {
5951                profileFd = profileFd.dup();
5952            }
5953            ProfilerInfo profilerInfo = profileFile == null ? null
5954                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5955            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5956                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5957                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5958                    isRestrictedBackupMode || !normalMode, app.persistent,
5959                    new Configuration(mConfiguration), app.compat,
5960                    getCommonServicesLocked(app.isolated),
5961                    mCoreSettingsObserver.getCoreSettingsLocked());
5962            updateLruProcessLocked(app, false, null);
5963            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5964        } catch (Exception e) {
5965            // todo: Yikes!  What should we do?  For now we will try to
5966            // start another process, but that could easily get us in
5967            // an infinite loop of restarting processes...
5968            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5969
5970            app.resetPackageList(mProcessStats);
5971            app.unlinkDeathRecipient();
5972            startProcessLocked(app, "bind fail", processName);
5973            return false;
5974        }
5975
5976        // Remove this record from the list of starting applications.
5977        mPersistentStartingProcesses.remove(app);
5978        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5979                "Attach application locked removing on hold: " + app);
5980        mProcessesOnHold.remove(app);
5981
5982        boolean badApp = false;
5983        boolean didSomething = false;
5984
5985        // See if the top visible activity is waiting to run in this process...
5986        if (normalMode) {
5987            try {
5988                if (mStackSupervisor.attachApplicationLocked(app)) {
5989                    didSomething = true;
5990                }
5991            } catch (Exception e) {
5992                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5993                badApp = true;
5994            }
5995        }
5996
5997        // Find any services that should be running in this process...
5998        if (!badApp) {
5999            try {
6000                didSomething |= mServices.attachApplicationLocked(app, processName);
6001            } catch (Exception e) {
6002                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6003                badApp = true;
6004            }
6005        }
6006
6007        // Check if a next-broadcast receiver is in this process...
6008        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6009            try {
6010                didSomething |= sendPendingBroadcastsLocked(app);
6011            } catch (Exception e) {
6012                // If the app died trying to launch the receiver we declare it 'bad'
6013                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6014                badApp = true;
6015            }
6016        }
6017
6018        // Check whether the next backup agent is in this process...
6019        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6020            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6021            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6022            try {
6023                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6024                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6025                        mBackupTarget.backupMode);
6026            } catch (Exception e) {
6027                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6028                badApp = true;
6029            }
6030        }
6031
6032        if (badApp) {
6033            app.kill("error during init", true);
6034            handleAppDiedLocked(app, false, true);
6035            return false;
6036        }
6037
6038        if (!didSomething) {
6039            updateOomAdjLocked();
6040        }
6041
6042        return true;
6043    }
6044
6045    @Override
6046    public final void attachApplication(IApplicationThread thread) {
6047        synchronized (this) {
6048            int callingPid = Binder.getCallingPid();
6049            final long origId = Binder.clearCallingIdentity();
6050            attachApplicationLocked(thread, callingPid);
6051            Binder.restoreCallingIdentity(origId);
6052        }
6053    }
6054
6055    @Override
6056    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6057        final long origId = Binder.clearCallingIdentity();
6058        synchronized (this) {
6059            ActivityStack stack = ActivityRecord.getStackLocked(token);
6060            if (stack != null) {
6061                ActivityRecord r =
6062                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6063                if (stopProfiling) {
6064                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6065                        try {
6066                            mProfileFd.close();
6067                        } catch (IOException e) {
6068                        }
6069                        clearProfilerLocked();
6070                    }
6071                }
6072            }
6073        }
6074        Binder.restoreCallingIdentity(origId);
6075    }
6076
6077    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6078        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6079                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6080    }
6081
6082    void enableScreenAfterBoot() {
6083        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6084                SystemClock.uptimeMillis());
6085        mWindowManager.enableScreenAfterBoot();
6086
6087        synchronized (this) {
6088            updateEventDispatchingLocked();
6089        }
6090    }
6091
6092    @Override
6093    public void showBootMessage(final CharSequence msg, final boolean always) {
6094        enforceNotIsolatedCaller("showBootMessage");
6095        mWindowManager.showBootMessage(msg, always);
6096    }
6097
6098    @Override
6099    public void keyguardWaitingForActivityDrawn() {
6100        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6101        final long token = Binder.clearCallingIdentity();
6102        try {
6103            synchronized (this) {
6104                if (DEBUG_LOCKSCREEN) logLockScreen("");
6105                mWindowManager.keyguardWaitingForActivityDrawn();
6106                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6107                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6108                    updateSleepIfNeededLocked();
6109                }
6110            }
6111        } finally {
6112            Binder.restoreCallingIdentity(token);
6113        }
6114    }
6115
6116    final void finishBooting() {
6117        synchronized (this) {
6118            if (!mBootAnimationComplete) {
6119                mCallFinishBooting = true;
6120                return;
6121            }
6122            mCallFinishBooting = false;
6123        }
6124
6125        ArraySet<String> completedIsas = new ArraySet<String>();
6126        for (String abi : Build.SUPPORTED_ABIS) {
6127            Process.establishZygoteConnectionForAbi(abi);
6128            final String instructionSet = VMRuntime.getInstructionSet(abi);
6129            if (!completedIsas.contains(instructionSet)) {
6130                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6131                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6132                }
6133                completedIsas.add(instructionSet);
6134            }
6135        }
6136
6137        IntentFilter pkgFilter = new IntentFilter();
6138        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6139        pkgFilter.addDataScheme("package");
6140        mContext.registerReceiver(new BroadcastReceiver() {
6141            @Override
6142            public void onReceive(Context context, Intent intent) {
6143                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6144                if (pkgs != null) {
6145                    for (String pkg : pkgs) {
6146                        synchronized (ActivityManagerService.this) {
6147                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6148                                    0, "finished booting")) {
6149                                setResultCode(Activity.RESULT_OK);
6150                                return;
6151                            }
6152                        }
6153                    }
6154                }
6155            }
6156        }, pkgFilter);
6157
6158        // Let system services know.
6159        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6160
6161        synchronized (this) {
6162            // Ensure that any processes we had put on hold are now started
6163            // up.
6164            final int NP = mProcessesOnHold.size();
6165            if (NP > 0) {
6166                ArrayList<ProcessRecord> procs =
6167                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6168                for (int ip=0; ip<NP; ip++) {
6169                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6170                            + procs.get(ip));
6171                    startProcessLocked(procs.get(ip), "on-hold", null);
6172                }
6173            }
6174
6175            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6176                // Start looking for apps that are abusing wake locks.
6177                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6178                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6179                // Tell anyone interested that we are done booting!
6180                SystemProperties.set("sys.boot_completed", "1");
6181
6182                // And trigger dev.bootcomplete if we are not showing encryption progress
6183                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6184                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6185                    SystemProperties.set("dev.bootcomplete", "1");
6186                }
6187                for (int i=0; i<mStartedUsers.size(); i++) {
6188                    UserStartedState uss = mStartedUsers.valueAt(i);
6189                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6190                        uss.mState = UserStartedState.STATE_RUNNING;
6191                        final int userId = mStartedUsers.keyAt(i);
6192                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6193                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6194                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6195                        broadcastIntentLocked(null, null, intent, null,
6196                                new IIntentReceiver.Stub() {
6197                                    @Override
6198                                    public void performReceive(Intent intent, int resultCode,
6199                                            String data, Bundle extras, boolean ordered,
6200                                            boolean sticky, int sendingUser) {
6201                                        synchronized (ActivityManagerService.this) {
6202                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6203                                                    true, false);
6204                                        }
6205                                    }
6206                                },
6207                                0, null, null,
6208                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6209                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6210                                userId);
6211                    }
6212                }
6213                scheduleStartProfilesLocked();
6214            }
6215        }
6216    }
6217
6218    @Override
6219    public void bootAnimationComplete() {
6220        final boolean callFinishBooting;
6221        synchronized (this) {
6222            callFinishBooting = mCallFinishBooting;
6223            mBootAnimationComplete = true;
6224        }
6225        if (callFinishBooting) {
6226            finishBooting();
6227        }
6228    }
6229
6230    @Override
6231    public void systemBackupRestored() {
6232        synchronized (this) {
6233            if (mSystemReady) {
6234                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6235            } else {
6236                Slog.w(TAG, "System backup restored before system is ready");
6237            }
6238        }
6239    }
6240
6241    final void ensureBootCompleted() {
6242        boolean booting;
6243        boolean enableScreen;
6244        synchronized (this) {
6245            booting = mBooting;
6246            mBooting = false;
6247            enableScreen = !mBooted;
6248            mBooted = true;
6249        }
6250
6251        if (booting) {
6252            finishBooting();
6253        }
6254
6255        if (enableScreen) {
6256            enableScreenAfterBoot();
6257        }
6258    }
6259
6260    @Override
6261    public final void activityResumed(IBinder token) {
6262        final long origId = Binder.clearCallingIdentity();
6263        synchronized(this) {
6264            ActivityStack stack = ActivityRecord.getStackLocked(token);
6265            if (stack != null) {
6266                ActivityRecord.activityResumedLocked(token);
6267            }
6268        }
6269        Binder.restoreCallingIdentity(origId);
6270    }
6271
6272    @Override
6273    public final void activityPaused(IBinder token) {
6274        final long origId = Binder.clearCallingIdentity();
6275        synchronized(this) {
6276            ActivityStack stack = ActivityRecord.getStackLocked(token);
6277            if (stack != null) {
6278                stack.activityPausedLocked(token, false);
6279            }
6280        }
6281        Binder.restoreCallingIdentity(origId);
6282    }
6283
6284    @Override
6285    public final void activityStopped(IBinder token, Bundle icicle,
6286            PersistableBundle persistentState, CharSequence description) {
6287        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6288
6289        // Refuse possible leaked file descriptors
6290        if (icicle != null && icicle.hasFileDescriptors()) {
6291            throw new IllegalArgumentException("File descriptors passed in Bundle");
6292        }
6293
6294        final long origId = Binder.clearCallingIdentity();
6295
6296        synchronized (this) {
6297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6298            if (r != null) {
6299                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6300            }
6301        }
6302
6303        trimApplications();
6304
6305        Binder.restoreCallingIdentity(origId);
6306    }
6307
6308    @Override
6309    public final void activityDestroyed(IBinder token) {
6310        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6311        synchronized (this) {
6312            ActivityStack stack = ActivityRecord.getStackLocked(token);
6313            if (stack != null) {
6314                stack.activityDestroyedLocked(token);
6315            }
6316        }
6317    }
6318
6319    @Override
6320    public final void backgroundResourcesReleased(IBinder token) {
6321        final long origId = Binder.clearCallingIdentity();
6322        try {
6323            synchronized (this) {
6324                ActivityStack stack = ActivityRecord.getStackLocked(token);
6325                if (stack != null) {
6326                    stack.backgroundResourcesReleased();
6327                }
6328            }
6329        } finally {
6330            Binder.restoreCallingIdentity(origId);
6331        }
6332    }
6333
6334    @Override
6335    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6336        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6337    }
6338
6339    @Override
6340    public final void notifyEnterAnimationComplete(IBinder token) {
6341        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6342    }
6343
6344    @Override
6345    public String getCallingPackage(IBinder token) {
6346        synchronized (this) {
6347            ActivityRecord r = getCallingRecordLocked(token);
6348            return r != null ? r.info.packageName : null;
6349        }
6350    }
6351
6352    @Override
6353    public ComponentName getCallingActivity(IBinder token) {
6354        synchronized (this) {
6355            ActivityRecord r = getCallingRecordLocked(token);
6356            return r != null ? r.intent.getComponent() : null;
6357        }
6358    }
6359
6360    private ActivityRecord getCallingRecordLocked(IBinder token) {
6361        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6362        if (r == null) {
6363            return null;
6364        }
6365        return r.resultTo;
6366    }
6367
6368    @Override
6369    public ComponentName getActivityClassForToken(IBinder token) {
6370        synchronized(this) {
6371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6372            if (r == null) {
6373                return null;
6374            }
6375            return r.intent.getComponent();
6376        }
6377    }
6378
6379    @Override
6380    public String getPackageForToken(IBinder token) {
6381        synchronized(this) {
6382            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6383            if (r == null) {
6384                return null;
6385            }
6386            return r.packageName;
6387        }
6388    }
6389
6390    @Override
6391    public IIntentSender getIntentSender(int type,
6392            String packageName, IBinder token, String resultWho,
6393            int requestCode, Intent[] intents, String[] resolvedTypes,
6394            int flags, Bundle options, int userId) {
6395        enforceNotIsolatedCaller("getIntentSender");
6396        // Refuse possible leaked file descriptors
6397        if (intents != null) {
6398            if (intents.length < 1) {
6399                throw new IllegalArgumentException("Intents array length must be >= 1");
6400            }
6401            for (int i=0; i<intents.length; i++) {
6402                Intent intent = intents[i];
6403                if (intent != null) {
6404                    if (intent.hasFileDescriptors()) {
6405                        throw new IllegalArgumentException("File descriptors passed in Intent");
6406                    }
6407                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6408                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6409                        throw new IllegalArgumentException(
6410                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6411                    }
6412                    intents[i] = new Intent(intent);
6413                }
6414            }
6415            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6416                throw new IllegalArgumentException(
6417                        "Intent array length does not match resolvedTypes length");
6418            }
6419        }
6420        if (options != null) {
6421            if (options.hasFileDescriptors()) {
6422                throw new IllegalArgumentException("File descriptors passed in options");
6423            }
6424        }
6425
6426        synchronized(this) {
6427            int callingUid = Binder.getCallingUid();
6428            int origUserId = userId;
6429            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6430                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6431                    ALLOW_NON_FULL, "getIntentSender", null);
6432            if (origUserId == UserHandle.USER_CURRENT) {
6433                // We don't want to evaluate this until the pending intent is
6434                // actually executed.  However, we do want to always do the
6435                // security checking for it above.
6436                userId = UserHandle.USER_CURRENT;
6437            }
6438            try {
6439                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6440                    int uid = AppGlobals.getPackageManager()
6441                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6442                    if (!UserHandle.isSameApp(callingUid, uid)) {
6443                        String msg = "Permission Denial: getIntentSender() from pid="
6444                            + Binder.getCallingPid()
6445                            + ", uid=" + Binder.getCallingUid()
6446                            + ", (need uid=" + uid + ")"
6447                            + " is not allowed to send as package " + packageName;
6448                        Slog.w(TAG, msg);
6449                        throw new SecurityException(msg);
6450                    }
6451                }
6452
6453                return getIntentSenderLocked(type, packageName, callingUid, userId,
6454                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6455
6456            } catch (RemoteException e) {
6457                throw new SecurityException(e);
6458            }
6459        }
6460    }
6461
6462    IIntentSender getIntentSenderLocked(int type, String packageName,
6463            int callingUid, int userId, IBinder token, String resultWho,
6464            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6465            Bundle options) {
6466        if (DEBUG_MU)
6467            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6468        ActivityRecord activity = null;
6469        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6470            activity = ActivityRecord.isInStackLocked(token);
6471            if (activity == null) {
6472                return null;
6473            }
6474            if (activity.finishing) {
6475                return null;
6476            }
6477        }
6478
6479        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6480        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6481        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6482        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6483                |PendingIntent.FLAG_UPDATE_CURRENT);
6484
6485        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6486                type, packageName, activity, resultWho,
6487                requestCode, intents, resolvedTypes, flags, options, userId);
6488        WeakReference<PendingIntentRecord> ref;
6489        ref = mIntentSenderRecords.get(key);
6490        PendingIntentRecord rec = ref != null ? ref.get() : null;
6491        if (rec != null) {
6492            if (!cancelCurrent) {
6493                if (updateCurrent) {
6494                    if (rec.key.requestIntent != null) {
6495                        rec.key.requestIntent.replaceExtras(intents != null ?
6496                                intents[intents.length - 1] : null);
6497                    }
6498                    if (intents != null) {
6499                        intents[intents.length-1] = rec.key.requestIntent;
6500                        rec.key.allIntents = intents;
6501                        rec.key.allResolvedTypes = resolvedTypes;
6502                    } else {
6503                        rec.key.allIntents = null;
6504                        rec.key.allResolvedTypes = null;
6505                    }
6506                }
6507                return rec;
6508            }
6509            rec.canceled = true;
6510            mIntentSenderRecords.remove(key);
6511        }
6512        if (noCreate) {
6513            return rec;
6514        }
6515        rec = new PendingIntentRecord(this, key, callingUid);
6516        mIntentSenderRecords.put(key, rec.ref);
6517        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6518            if (activity.pendingResults == null) {
6519                activity.pendingResults
6520                        = new HashSet<WeakReference<PendingIntentRecord>>();
6521            }
6522            activity.pendingResults.add(rec.ref);
6523        }
6524        return rec;
6525    }
6526
6527    @Override
6528    public void cancelIntentSender(IIntentSender sender) {
6529        if (!(sender instanceof PendingIntentRecord)) {
6530            return;
6531        }
6532        synchronized(this) {
6533            PendingIntentRecord rec = (PendingIntentRecord)sender;
6534            try {
6535                int uid = AppGlobals.getPackageManager()
6536                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6537                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6538                    String msg = "Permission Denial: cancelIntentSender() from pid="
6539                        + Binder.getCallingPid()
6540                        + ", uid=" + Binder.getCallingUid()
6541                        + " is not allowed to cancel packges "
6542                        + rec.key.packageName;
6543                    Slog.w(TAG, msg);
6544                    throw new SecurityException(msg);
6545                }
6546            } catch (RemoteException e) {
6547                throw new SecurityException(e);
6548            }
6549            cancelIntentSenderLocked(rec, true);
6550        }
6551    }
6552
6553    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6554        rec.canceled = true;
6555        mIntentSenderRecords.remove(rec.key);
6556        if (cleanActivity && rec.key.activity != null) {
6557            rec.key.activity.pendingResults.remove(rec.ref);
6558        }
6559    }
6560
6561    @Override
6562    public String getPackageForIntentSender(IIntentSender pendingResult) {
6563        if (!(pendingResult instanceof PendingIntentRecord)) {
6564            return null;
6565        }
6566        try {
6567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6568            return res.key.packageName;
6569        } catch (ClassCastException e) {
6570        }
6571        return null;
6572    }
6573
6574    @Override
6575    public int getUidForIntentSender(IIntentSender sender) {
6576        if (sender instanceof PendingIntentRecord) {
6577            try {
6578                PendingIntentRecord res = (PendingIntentRecord)sender;
6579                return res.uid;
6580            } catch (ClassCastException e) {
6581            }
6582        }
6583        return -1;
6584    }
6585
6586    @Override
6587    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6588        if (!(pendingResult instanceof PendingIntentRecord)) {
6589            return false;
6590        }
6591        try {
6592            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6593            if (res.key.allIntents == null) {
6594                return false;
6595            }
6596            for (int i=0; i<res.key.allIntents.length; i++) {
6597                Intent intent = res.key.allIntents[i];
6598                if (intent.getPackage() != null && intent.getComponent() != null) {
6599                    return false;
6600                }
6601            }
6602            return true;
6603        } catch (ClassCastException e) {
6604        }
6605        return false;
6606    }
6607
6608    @Override
6609    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6610        if (!(pendingResult instanceof PendingIntentRecord)) {
6611            return false;
6612        }
6613        try {
6614            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6615            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6616                return true;
6617            }
6618            return false;
6619        } catch (ClassCastException e) {
6620        }
6621        return false;
6622    }
6623
6624    @Override
6625    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6626        if (!(pendingResult instanceof PendingIntentRecord)) {
6627            return null;
6628        }
6629        try {
6630            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6631            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6632        } catch (ClassCastException e) {
6633        }
6634        return null;
6635    }
6636
6637    @Override
6638    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6639        if (!(pendingResult instanceof PendingIntentRecord)) {
6640            return null;
6641        }
6642        try {
6643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6644            Intent intent = res.key.requestIntent;
6645            if (intent != null) {
6646                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6647                        || res.lastTagPrefix.equals(prefix))) {
6648                    return res.lastTag;
6649                }
6650                res.lastTagPrefix = prefix;
6651                StringBuilder sb = new StringBuilder(128);
6652                if (prefix != null) {
6653                    sb.append(prefix);
6654                }
6655                if (intent.getAction() != null) {
6656                    sb.append(intent.getAction());
6657                } else if (intent.getComponent() != null) {
6658                    intent.getComponent().appendShortString(sb);
6659                } else {
6660                    sb.append("?");
6661                }
6662                return res.lastTag = sb.toString();
6663            }
6664        } catch (ClassCastException e) {
6665        }
6666        return null;
6667    }
6668
6669    @Override
6670    public void setProcessLimit(int max) {
6671        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6672                "setProcessLimit()");
6673        synchronized (this) {
6674            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6675            mProcessLimitOverride = max;
6676        }
6677        trimApplications();
6678    }
6679
6680    @Override
6681    public int getProcessLimit() {
6682        synchronized (this) {
6683            return mProcessLimitOverride;
6684        }
6685    }
6686
6687    void foregroundTokenDied(ForegroundToken token) {
6688        synchronized (ActivityManagerService.this) {
6689            synchronized (mPidsSelfLocked) {
6690                ForegroundToken cur
6691                    = mForegroundProcesses.get(token.pid);
6692                if (cur != token) {
6693                    return;
6694                }
6695                mForegroundProcesses.remove(token.pid);
6696                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6697                if (pr == null) {
6698                    return;
6699                }
6700                pr.forcingToForeground = null;
6701                updateProcessForegroundLocked(pr, false, false);
6702            }
6703            updateOomAdjLocked();
6704        }
6705    }
6706
6707    @Override
6708    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6709        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6710                "setProcessForeground()");
6711        synchronized(this) {
6712            boolean changed = false;
6713
6714            synchronized (mPidsSelfLocked) {
6715                ProcessRecord pr = mPidsSelfLocked.get(pid);
6716                if (pr == null && isForeground) {
6717                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6718                    return;
6719                }
6720                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6721                if (oldToken != null) {
6722                    oldToken.token.unlinkToDeath(oldToken, 0);
6723                    mForegroundProcesses.remove(pid);
6724                    if (pr != null) {
6725                        pr.forcingToForeground = null;
6726                    }
6727                    changed = true;
6728                }
6729                if (isForeground && token != null) {
6730                    ForegroundToken newToken = new ForegroundToken() {
6731                        @Override
6732                        public void binderDied() {
6733                            foregroundTokenDied(this);
6734                        }
6735                    };
6736                    newToken.pid = pid;
6737                    newToken.token = token;
6738                    try {
6739                        token.linkToDeath(newToken, 0);
6740                        mForegroundProcesses.put(pid, newToken);
6741                        pr.forcingToForeground = token;
6742                        changed = true;
6743                    } catch (RemoteException e) {
6744                        // If the process died while doing this, we will later
6745                        // do the cleanup with the process death link.
6746                    }
6747                }
6748            }
6749
6750            if (changed) {
6751                updateOomAdjLocked();
6752            }
6753        }
6754    }
6755
6756    // =========================================================
6757    // PERMISSIONS
6758    // =========================================================
6759
6760    static class PermissionController extends IPermissionController.Stub {
6761        ActivityManagerService mActivityManagerService;
6762        PermissionController(ActivityManagerService activityManagerService) {
6763            mActivityManagerService = activityManagerService;
6764        }
6765
6766        @Override
6767        public boolean checkPermission(String permission, int pid, int uid) {
6768            return mActivityManagerService.checkPermission(permission, pid,
6769                    uid) == PackageManager.PERMISSION_GRANTED;
6770        }
6771    }
6772
6773    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6774        @Override
6775        public int checkComponentPermission(String permission, int pid, int uid,
6776                int owningUid, boolean exported) {
6777            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6778                    owningUid, exported);
6779        }
6780
6781        @Override
6782        public Object getAMSLock() {
6783            return ActivityManagerService.this;
6784        }
6785    }
6786
6787    /**
6788     * This can be called with or without the global lock held.
6789     */
6790    int checkComponentPermission(String permission, int pid, int uid,
6791            int owningUid, boolean exported) {
6792        if (pid == MY_PID) {
6793            return PackageManager.PERMISSION_GRANTED;
6794        }
6795        return ActivityManager.checkComponentPermission(permission, uid,
6796                owningUid, exported);
6797    }
6798
6799    /**
6800     * As the only public entry point for permissions checking, this method
6801     * can enforce the semantic that requesting a check on a null global
6802     * permission is automatically denied.  (Internally a null permission
6803     * string is used when calling {@link #checkComponentPermission} in cases
6804     * when only uid-based security is needed.)
6805     *
6806     * This can be called with or without the global lock held.
6807     */
6808    @Override
6809    public int checkPermission(String permission, int pid, int uid) {
6810        if (permission == null) {
6811            return PackageManager.PERMISSION_DENIED;
6812        }
6813        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6814    }
6815
6816    @Override
6817    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6818        if (permission == null) {
6819            return PackageManager.PERMISSION_DENIED;
6820        }
6821
6822        // We might be performing an operation on behalf of an indirect binder
6823        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6824        // client identity accordingly before proceeding.
6825        Identity tlsIdentity = sCallerIdentity.get();
6826        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6827            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6828                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6829            uid = tlsIdentity.uid;
6830            pid = tlsIdentity.pid;
6831        }
6832
6833        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6834    }
6835
6836    /**
6837     * Binder IPC calls go through the public entry point.
6838     * This can be called with or without the global lock held.
6839     */
6840    int checkCallingPermission(String permission) {
6841        return checkPermission(permission,
6842                Binder.getCallingPid(),
6843                UserHandle.getAppId(Binder.getCallingUid()));
6844    }
6845
6846    /**
6847     * This can be called with or without the global lock held.
6848     */
6849    void enforceCallingPermission(String permission, String func) {
6850        if (checkCallingPermission(permission)
6851                == PackageManager.PERMISSION_GRANTED) {
6852            return;
6853        }
6854
6855        String msg = "Permission Denial: " + func + " from pid="
6856                + Binder.getCallingPid()
6857                + ", uid=" + Binder.getCallingUid()
6858                + " requires " + permission;
6859        Slog.w(TAG, msg);
6860        throw new SecurityException(msg);
6861    }
6862
6863    /**
6864     * Determine if UID is holding permissions required to access {@link Uri} in
6865     * the given {@link ProviderInfo}. Final permission checking is always done
6866     * in {@link ContentProvider}.
6867     */
6868    private final boolean checkHoldingPermissionsLocked(
6869            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6870        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6871                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6872        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6873            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6874                    != PERMISSION_GRANTED) {
6875                return false;
6876            }
6877        }
6878        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6879    }
6880
6881    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6882            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6883        if (pi.applicationInfo.uid == uid) {
6884            return true;
6885        } else if (!pi.exported) {
6886            return false;
6887        }
6888
6889        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6890        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6891        try {
6892            // check if target holds top-level <provider> permissions
6893            if (!readMet && pi.readPermission != null && considerUidPermissions
6894                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6895                readMet = true;
6896            }
6897            if (!writeMet && pi.writePermission != null && considerUidPermissions
6898                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6899                writeMet = true;
6900            }
6901
6902            // track if unprotected read/write is allowed; any denied
6903            // <path-permission> below removes this ability
6904            boolean allowDefaultRead = pi.readPermission == null;
6905            boolean allowDefaultWrite = pi.writePermission == null;
6906
6907            // check if target holds any <path-permission> that match uri
6908            final PathPermission[] pps = pi.pathPermissions;
6909            if (pps != null) {
6910                final String path = grantUri.uri.getPath();
6911                int i = pps.length;
6912                while (i > 0 && (!readMet || !writeMet)) {
6913                    i--;
6914                    PathPermission pp = pps[i];
6915                    if (pp.match(path)) {
6916                        if (!readMet) {
6917                            final String pprperm = pp.getReadPermission();
6918                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6919                                    + pprperm + " for " + pp.getPath()
6920                                    + ": match=" + pp.match(path)
6921                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6922                            if (pprperm != null) {
6923                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6924                                        == PERMISSION_GRANTED) {
6925                                    readMet = true;
6926                                } else {
6927                                    allowDefaultRead = false;
6928                                }
6929                            }
6930                        }
6931                        if (!writeMet) {
6932                            final String ppwperm = pp.getWritePermission();
6933                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6934                                    + ppwperm + " for " + pp.getPath()
6935                                    + ": match=" + pp.match(path)
6936                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6937                            if (ppwperm != null) {
6938                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6939                                        == PERMISSION_GRANTED) {
6940                                    writeMet = true;
6941                                } else {
6942                                    allowDefaultWrite = false;
6943                                }
6944                            }
6945                        }
6946                    }
6947                }
6948            }
6949
6950            // grant unprotected <provider> read/write, if not blocked by
6951            // <path-permission> above
6952            if (allowDefaultRead) readMet = true;
6953            if (allowDefaultWrite) writeMet = true;
6954
6955        } catch (RemoteException e) {
6956            return false;
6957        }
6958
6959        return readMet && writeMet;
6960    }
6961
6962    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6963        ProviderInfo pi = null;
6964        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6965        if (cpr != null) {
6966            pi = cpr.info;
6967        } else {
6968            try {
6969                pi = AppGlobals.getPackageManager().resolveContentProvider(
6970                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6971            } catch (RemoteException ex) {
6972            }
6973        }
6974        return pi;
6975    }
6976
6977    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6978        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6979        if (targetUris != null) {
6980            return targetUris.get(grantUri);
6981        }
6982        return null;
6983    }
6984
6985    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6986            String targetPkg, int targetUid, GrantUri grantUri) {
6987        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6988        if (targetUris == null) {
6989            targetUris = Maps.newArrayMap();
6990            mGrantedUriPermissions.put(targetUid, targetUris);
6991        }
6992
6993        UriPermission perm = targetUris.get(grantUri);
6994        if (perm == null) {
6995            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6996            targetUris.put(grantUri, perm);
6997        }
6998
6999        return perm;
7000    }
7001
7002    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7003            final int modeFlags) {
7004        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7005        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7006                : UriPermission.STRENGTH_OWNED;
7007
7008        // Root gets to do everything.
7009        if (uid == 0) {
7010            return true;
7011        }
7012
7013        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7014        if (perms == null) return false;
7015
7016        // First look for exact match
7017        final UriPermission exactPerm = perms.get(grantUri);
7018        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7019            return true;
7020        }
7021
7022        // No exact match, look for prefixes
7023        final int N = perms.size();
7024        for (int i = 0; i < N; i++) {
7025            final UriPermission perm = perms.valueAt(i);
7026            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7027                    && perm.getStrength(modeFlags) >= minStrength) {
7028                return true;
7029            }
7030        }
7031
7032        return false;
7033    }
7034
7035    /**
7036     * @param uri This uri must NOT contain an embedded userId.
7037     * @param userId The userId in which the uri is to be resolved.
7038     */
7039    @Override
7040    public int checkUriPermission(Uri uri, int pid, int uid,
7041            final int modeFlags, int userId, IBinder callerToken) {
7042        enforceNotIsolatedCaller("checkUriPermission");
7043
7044        // Another redirected-binder-call permissions check as in
7045        // {@link checkPermissionWithToken}.
7046        Identity tlsIdentity = sCallerIdentity.get();
7047        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7048            uid = tlsIdentity.uid;
7049            pid = tlsIdentity.pid;
7050        }
7051
7052        // Our own process gets to do everything.
7053        if (pid == MY_PID) {
7054            return PackageManager.PERMISSION_GRANTED;
7055        }
7056        synchronized (this) {
7057            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7058                    ? PackageManager.PERMISSION_GRANTED
7059                    : PackageManager.PERMISSION_DENIED;
7060        }
7061    }
7062
7063    /**
7064     * Check if the targetPkg can be granted permission to access uri by
7065     * the callingUid using the given modeFlags.  Throws a security exception
7066     * if callingUid is not allowed to do this.  Returns the uid of the target
7067     * if the URI permission grant should be performed; returns -1 if it is not
7068     * needed (for example targetPkg already has permission to access the URI).
7069     * If you already know the uid of the target, you can supply it in
7070     * lastTargetUid else set that to -1.
7071     */
7072    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7073            final int modeFlags, int lastTargetUid) {
7074        if (!Intent.isAccessUriMode(modeFlags)) {
7075            return -1;
7076        }
7077
7078        if (targetPkg != null) {
7079            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7080                    "Checking grant " + targetPkg + " permission to " + grantUri);
7081        }
7082
7083        final IPackageManager pm = AppGlobals.getPackageManager();
7084
7085        // If this is not a content: uri, we can't do anything with it.
7086        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7087            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7088                    "Can't grant URI permission for non-content URI: " + grantUri);
7089            return -1;
7090        }
7091
7092        final String authority = grantUri.uri.getAuthority();
7093        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7094        if (pi == null) {
7095            Slog.w(TAG, "No content provider found for permission check: " +
7096                    grantUri.uri.toSafeString());
7097            return -1;
7098        }
7099
7100        int targetUid = lastTargetUid;
7101        if (targetUid < 0 && targetPkg != null) {
7102            try {
7103                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7104                if (targetUid < 0) {
7105                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7106                            "Can't grant URI permission no uid for: " + targetPkg);
7107                    return -1;
7108                }
7109            } catch (RemoteException ex) {
7110                return -1;
7111            }
7112        }
7113
7114        if (targetUid >= 0) {
7115            // First...  does the target actually need this permission?
7116            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7117                // No need to grant the target this permission.
7118                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7119                        "Target " + targetPkg + " already has full permission to " + grantUri);
7120                return -1;
7121            }
7122        } else {
7123            // First...  there is no target package, so can anyone access it?
7124            boolean allowed = pi.exported;
7125            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7126                if (pi.readPermission != null) {
7127                    allowed = false;
7128                }
7129            }
7130            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7131                if (pi.writePermission != null) {
7132                    allowed = false;
7133                }
7134            }
7135            if (allowed) {
7136                return -1;
7137            }
7138        }
7139
7140        /* There is a special cross user grant if:
7141         * - The target is on another user.
7142         * - Apps on the current user can access the uri without any uid permissions.
7143         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7144         * grant uri permissions.
7145         */
7146        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7147                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7148                modeFlags, false /*without considering the uid permissions*/);
7149
7150        // Second...  is the provider allowing granting of URI permissions?
7151        if (!specialCrossUserGrant) {
7152            if (!pi.grantUriPermissions) {
7153                throw new SecurityException("Provider " + pi.packageName
7154                        + "/" + pi.name
7155                        + " does not allow granting of Uri permissions (uri "
7156                        + grantUri + ")");
7157            }
7158            if (pi.uriPermissionPatterns != null) {
7159                final int N = pi.uriPermissionPatterns.length;
7160                boolean allowed = false;
7161                for (int i=0; i<N; i++) {
7162                    if (pi.uriPermissionPatterns[i] != null
7163                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7164                        allowed = true;
7165                        break;
7166                    }
7167                }
7168                if (!allowed) {
7169                    throw new SecurityException("Provider " + pi.packageName
7170                            + "/" + pi.name
7171                            + " does not allow granting of permission to path of Uri "
7172                            + grantUri);
7173                }
7174            }
7175        }
7176
7177        // Third...  does the caller itself have permission to access
7178        // this uri?
7179        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7180            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7181                // Require they hold a strong enough Uri permission
7182                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7183                    throw new SecurityException("Uid " + callingUid
7184                            + " does not have permission to uri " + grantUri);
7185                }
7186            }
7187        }
7188        return targetUid;
7189    }
7190
7191    /**
7192     * @param uri This uri must NOT contain an embedded userId.
7193     * @param userId The userId in which the uri is to be resolved.
7194     */
7195    @Override
7196    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7197            final int modeFlags, int userId) {
7198        enforceNotIsolatedCaller("checkGrantUriPermission");
7199        synchronized(this) {
7200            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7201                    new GrantUri(userId, uri, false), modeFlags, -1);
7202        }
7203    }
7204
7205    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7206            final int modeFlags, UriPermissionOwner owner) {
7207        if (!Intent.isAccessUriMode(modeFlags)) {
7208            return;
7209        }
7210
7211        // So here we are: the caller has the assumed permission
7212        // to the uri, and the target doesn't.  Let's now give this to
7213        // the target.
7214
7215        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7216                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7217
7218        final String authority = grantUri.uri.getAuthority();
7219        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7220        if (pi == null) {
7221            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7222            return;
7223        }
7224
7225        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7226            grantUri.prefix = true;
7227        }
7228        final UriPermission perm = findOrCreateUriPermissionLocked(
7229                pi.packageName, targetPkg, targetUid, grantUri);
7230        perm.grantModes(modeFlags, owner);
7231    }
7232
7233    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7234            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7235        if (targetPkg == null) {
7236            throw new NullPointerException("targetPkg");
7237        }
7238        int targetUid;
7239        final IPackageManager pm = AppGlobals.getPackageManager();
7240        try {
7241            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7242        } catch (RemoteException ex) {
7243            return;
7244        }
7245
7246        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7247                targetUid);
7248        if (targetUid < 0) {
7249            return;
7250        }
7251
7252        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7253                owner);
7254    }
7255
7256    static class NeededUriGrants extends ArrayList<GrantUri> {
7257        final String targetPkg;
7258        final int targetUid;
7259        final int flags;
7260
7261        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7262            this.targetPkg = targetPkg;
7263            this.targetUid = targetUid;
7264            this.flags = flags;
7265        }
7266    }
7267
7268    /**
7269     * Like checkGrantUriPermissionLocked, but takes an Intent.
7270     */
7271    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7272            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7273        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7274                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7275                + " clip=" + (intent != null ? intent.getClipData() : null)
7276                + " from " + intent + "; flags=0x"
7277                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7278
7279        if (targetPkg == null) {
7280            throw new NullPointerException("targetPkg");
7281        }
7282
7283        if (intent == null) {
7284            return null;
7285        }
7286        Uri data = intent.getData();
7287        ClipData clip = intent.getClipData();
7288        if (data == null && clip == null) {
7289            return null;
7290        }
7291        // Default userId for uris in the intent (if they don't specify it themselves)
7292        int contentUserHint = intent.getContentUserHint();
7293        if (contentUserHint == UserHandle.USER_CURRENT) {
7294            contentUserHint = UserHandle.getUserId(callingUid);
7295        }
7296        final IPackageManager pm = AppGlobals.getPackageManager();
7297        int targetUid;
7298        if (needed != null) {
7299            targetUid = needed.targetUid;
7300        } else {
7301            try {
7302                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7303            } catch (RemoteException ex) {
7304                return null;
7305            }
7306            if (targetUid < 0) {
7307                if (DEBUG_URI_PERMISSION) {
7308                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7309                            + " on user " + targetUserId);
7310                }
7311                return null;
7312            }
7313        }
7314        if (data != null) {
7315            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7316            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7317                    targetUid);
7318            if (targetUid > 0) {
7319                if (needed == null) {
7320                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7321                }
7322                needed.add(grantUri);
7323            }
7324        }
7325        if (clip != null) {
7326            for (int i=0; i<clip.getItemCount(); i++) {
7327                Uri uri = clip.getItemAt(i).getUri();
7328                if (uri != null) {
7329                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7330                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7331                            targetUid);
7332                    if (targetUid > 0) {
7333                        if (needed == null) {
7334                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7335                        }
7336                        needed.add(grantUri);
7337                    }
7338                } else {
7339                    Intent clipIntent = clip.getItemAt(i).getIntent();
7340                    if (clipIntent != null) {
7341                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7342                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7343                        if (newNeeded != null) {
7344                            needed = newNeeded;
7345                        }
7346                    }
7347                }
7348            }
7349        }
7350
7351        return needed;
7352    }
7353
7354    /**
7355     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7356     */
7357    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7358            UriPermissionOwner owner) {
7359        if (needed != null) {
7360            for (int i=0; i<needed.size(); i++) {
7361                GrantUri grantUri = needed.get(i);
7362                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7363                        grantUri, needed.flags, owner);
7364            }
7365        }
7366    }
7367
7368    void grantUriPermissionFromIntentLocked(int callingUid,
7369            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7370        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7371                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7372        if (needed == null) {
7373            return;
7374        }
7375
7376        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7377    }
7378
7379    /**
7380     * @param uri This uri must NOT contain an embedded userId.
7381     * @param userId The userId in which the uri is to be resolved.
7382     */
7383    @Override
7384    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7385            final int modeFlags, int userId) {
7386        enforceNotIsolatedCaller("grantUriPermission");
7387        GrantUri grantUri = new GrantUri(userId, uri, false);
7388        synchronized(this) {
7389            final ProcessRecord r = getRecordForAppLocked(caller);
7390            if (r == null) {
7391                throw new SecurityException("Unable to find app for caller "
7392                        + caller
7393                        + " when granting permission to uri " + grantUri);
7394            }
7395            if (targetPkg == null) {
7396                throw new IllegalArgumentException("null target");
7397            }
7398            if (grantUri == null) {
7399                throw new IllegalArgumentException("null uri");
7400            }
7401
7402            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7403                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7404                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7406
7407            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7408                    UserHandle.getUserId(r.uid));
7409        }
7410    }
7411
7412    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7413        if (perm.modeFlags == 0) {
7414            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7415                    perm.targetUid);
7416            if (perms != null) {
7417                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7418                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7419
7420                perms.remove(perm.uri);
7421                if (perms.isEmpty()) {
7422                    mGrantedUriPermissions.remove(perm.targetUid);
7423                }
7424            }
7425        }
7426    }
7427
7428    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7429        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7430
7431        final IPackageManager pm = AppGlobals.getPackageManager();
7432        final String authority = grantUri.uri.getAuthority();
7433        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7434        if (pi == null) {
7435            Slog.w(TAG, "No content provider found for permission revoke: "
7436                    + grantUri.toSafeString());
7437            return;
7438        }
7439
7440        // Does the caller have this permission on the URI?
7441        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7442            // If they don't have direct access to the URI, then revoke any
7443            // ownerless URI permissions that have been granted to them.
7444            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7445            if (perms != null) {
7446                boolean persistChanged = false;
7447                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7448                    final UriPermission perm = it.next();
7449                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7450                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7451                        if (DEBUG_URI_PERMISSION)
7452                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7453                                    " permission to " + perm.uri);
7454                        persistChanged |= perm.revokeModes(
7455                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7456                        if (perm.modeFlags == 0) {
7457                            it.remove();
7458                        }
7459                    }
7460                }
7461                if (perms.isEmpty()) {
7462                    mGrantedUriPermissions.remove(callingUid);
7463                }
7464                if (persistChanged) {
7465                    schedulePersistUriGrants();
7466                }
7467            }
7468            return;
7469        }
7470
7471        boolean persistChanged = false;
7472
7473        // Go through all of the permissions and remove any that match.
7474        int N = mGrantedUriPermissions.size();
7475        for (int i = 0; i < N; i++) {
7476            final int targetUid = mGrantedUriPermissions.keyAt(i);
7477            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7478
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,
7485                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7486                    persistChanged |= perm.revokeModes(
7487                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7488                    if (perm.modeFlags == 0) {
7489                        it.remove();
7490                    }
7491                }
7492            }
7493
7494            if (perms.isEmpty()) {
7495                mGrantedUriPermissions.remove(targetUid);
7496                N--;
7497                i--;
7498            }
7499        }
7500
7501        if (persistChanged) {
7502            schedulePersistUriGrants();
7503        }
7504    }
7505
7506    /**
7507     * @param uri This uri must NOT contain an embedded userId.
7508     * @param userId The userId in which the uri is to be resolved.
7509     */
7510    @Override
7511    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7512            int userId) {
7513        enforceNotIsolatedCaller("revokeUriPermission");
7514        synchronized(this) {
7515            final ProcessRecord r = getRecordForAppLocked(caller);
7516            if (r == null) {
7517                throw new SecurityException("Unable to find app for caller "
7518                        + caller
7519                        + " when revoking permission to uri " + uri);
7520            }
7521            if (uri == null) {
7522                Slog.w(TAG, "revokeUriPermission: null uri");
7523                return;
7524            }
7525
7526            if (!Intent.isAccessUriMode(modeFlags)) {
7527                return;
7528            }
7529
7530            final IPackageManager pm = AppGlobals.getPackageManager();
7531            final String authority = uri.getAuthority();
7532            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7533            if (pi == null) {
7534                Slog.w(TAG, "No content provider found for permission revoke: "
7535                        + uri.toSafeString());
7536                return;
7537            }
7538
7539            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7540        }
7541    }
7542
7543    /**
7544     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7545     * given package.
7546     *
7547     * @param packageName Package name to match, or {@code null} to apply to all
7548     *            packages.
7549     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7550     *            to all users.
7551     * @param persistable If persistable grants should be removed.
7552     */
7553    private void removeUriPermissionsForPackageLocked(
7554            String packageName, int userHandle, boolean persistable) {
7555        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7556            throw new IllegalArgumentException("Must narrow by either package or user");
7557        }
7558
7559        boolean persistChanged = false;
7560
7561        int N = mGrantedUriPermissions.size();
7562        for (int i = 0; i < N; i++) {
7563            final int targetUid = mGrantedUriPermissions.keyAt(i);
7564            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7565
7566            // Only inspect grants matching user
7567            if (userHandle == UserHandle.USER_ALL
7568                    || userHandle == UserHandle.getUserId(targetUid)) {
7569                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7570                    final UriPermission perm = it.next();
7571
7572                    // Only inspect grants matching package
7573                    if (packageName == null || perm.sourcePkg.equals(packageName)
7574                            || perm.targetPkg.equals(packageName)) {
7575                        persistChanged |= perm.revokeModes(persistable
7576                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7577
7578                        // Only remove when no modes remain; any persisted grants
7579                        // will keep this alive.
7580                        if (perm.modeFlags == 0) {
7581                            it.remove();
7582                        }
7583                    }
7584                }
7585
7586                if (perms.isEmpty()) {
7587                    mGrantedUriPermissions.remove(targetUid);
7588                    N--;
7589                    i--;
7590                }
7591            }
7592        }
7593
7594        if (persistChanged) {
7595            schedulePersistUriGrants();
7596        }
7597    }
7598
7599    @Override
7600    public IBinder newUriPermissionOwner(String name) {
7601        enforceNotIsolatedCaller("newUriPermissionOwner");
7602        synchronized(this) {
7603            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7604            return owner.getExternalTokenLocked();
7605        }
7606    }
7607
7608    /**
7609     * @param uri This uri must NOT contain an embedded userId.
7610     * @param sourceUserId The userId in which the uri is to be resolved.
7611     * @param targetUserId The userId of the app that receives the grant.
7612     */
7613    @Override
7614    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7615            final int modeFlags, int sourceUserId, int targetUserId) {
7616        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7617                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7618        synchronized(this) {
7619            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7620            if (owner == null) {
7621                throw new IllegalArgumentException("Unknown owner: " + token);
7622            }
7623            if (fromUid != Binder.getCallingUid()) {
7624                if (Binder.getCallingUid() != Process.myUid()) {
7625                    // Only system code can grant URI permissions on behalf
7626                    // of other users.
7627                    throw new SecurityException("nice try");
7628                }
7629            }
7630            if (targetPkg == null) {
7631                throw new IllegalArgumentException("null target");
7632            }
7633            if (uri == null) {
7634                throw new IllegalArgumentException("null uri");
7635            }
7636
7637            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7638                    modeFlags, owner, targetUserId);
7639        }
7640    }
7641
7642    /**
7643     * @param uri This uri must NOT contain an embedded userId.
7644     * @param userId The userId in which the uri is to be resolved.
7645     */
7646    @Override
7647    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7648        synchronized(this) {
7649            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7650            if (owner == null) {
7651                throw new IllegalArgumentException("Unknown owner: " + token);
7652            }
7653
7654            if (uri == null) {
7655                owner.removeUriPermissionsLocked(mode);
7656            } else {
7657                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7658            }
7659        }
7660    }
7661
7662    private void schedulePersistUriGrants() {
7663        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7664            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7665                    10 * DateUtils.SECOND_IN_MILLIS);
7666        }
7667    }
7668
7669    private void writeGrantedUriPermissions() {
7670        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7671
7672        // Snapshot permissions so we can persist without lock
7673        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7674        synchronized (this) {
7675            final int size = mGrantedUriPermissions.size();
7676            for (int i = 0; i < size; i++) {
7677                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7678                for (UriPermission perm : perms.values()) {
7679                    if (perm.persistedModeFlags != 0) {
7680                        persist.add(perm.snapshot());
7681                    }
7682                }
7683            }
7684        }
7685
7686        FileOutputStream fos = null;
7687        try {
7688            fos = mGrantFile.startWrite();
7689
7690            XmlSerializer out = new FastXmlSerializer();
7691            out.setOutput(fos, "utf-8");
7692            out.startDocument(null, true);
7693            out.startTag(null, TAG_URI_GRANTS);
7694            for (UriPermission.Snapshot perm : persist) {
7695                out.startTag(null, TAG_URI_GRANT);
7696                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7697                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7698                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7699                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7700                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7701                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7702                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7703                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7704                out.endTag(null, TAG_URI_GRANT);
7705            }
7706            out.endTag(null, TAG_URI_GRANTS);
7707            out.endDocument();
7708
7709            mGrantFile.finishWrite(fos);
7710        } catch (IOException e) {
7711            if (fos != null) {
7712                mGrantFile.failWrite(fos);
7713            }
7714        }
7715    }
7716
7717    private void readGrantedUriPermissionsLocked() {
7718        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7719
7720        final long now = System.currentTimeMillis();
7721
7722        FileInputStream fis = null;
7723        try {
7724            fis = mGrantFile.openRead();
7725            final XmlPullParser in = Xml.newPullParser();
7726            in.setInput(fis, null);
7727
7728            int type;
7729            while ((type = in.next()) != END_DOCUMENT) {
7730                final String tag = in.getName();
7731                if (type == START_TAG) {
7732                    if (TAG_URI_GRANT.equals(tag)) {
7733                        final int sourceUserId;
7734                        final int targetUserId;
7735                        final int userHandle = readIntAttribute(in,
7736                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7737                        if (userHandle != UserHandle.USER_NULL) {
7738                            // For backwards compatibility.
7739                            sourceUserId = userHandle;
7740                            targetUserId = userHandle;
7741                        } else {
7742                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7743                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7744                        }
7745                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7746                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7747                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7748                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7749                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7750                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7751
7752                        // Sanity check that provider still belongs to source package
7753                        final ProviderInfo pi = getProviderInfoLocked(
7754                                uri.getAuthority(), sourceUserId);
7755                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7756                            int targetUid = -1;
7757                            try {
7758                                targetUid = AppGlobals.getPackageManager()
7759                                        .getPackageUid(targetPkg, targetUserId);
7760                            } catch (RemoteException e) {
7761                            }
7762                            if (targetUid != -1) {
7763                                final UriPermission perm = findOrCreateUriPermissionLocked(
7764                                        sourcePkg, targetPkg, targetUid,
7765                                        new GrantUri(sourceUserId, uri, prefix));
7766                                perm.initPersistedModes(modeFlags, createdTime);
7767                            }
7768                        } else {
7769                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7770                                    + " but instead found " + pi);
7771                        }
7772                    }
7773                }
7774            }
7775        } catch (FileNotFoundException e) {
7776            // Missing grants is okay
7777        } catch (IOException e) {
7778            Slog.wtf(TAG, "Failed reading Uri grants", e);
7779        } catch (XmlPullParserException e) {
7780            Slog.wtf(TAG, "Failed reading Uri grants", e);
7781        } finally {
7782            IoUtils.closeQuietly(fis);
7783        }
7784    }
7785
7786    /**
7787     * @param uri This uri must NOT contain an embedded userId.
7788     * @param userId The userId in which the uri is to be resolved.
7789     */
7790    @Override
7791    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7792        enforceNotIsolatedCaller("takePersistableUriPermission");
7793
7794        Preconditions.checkFlagsArgument(modeFlags,
7795                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7796
7797        synchronized (this) {
7798            final int callingUid = Binder.getCallingUid();
7799            boolean persistChanged = false;
7800            GrantUri grantUri = new GrantUri(userId, uri, false);
7801
7802            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7803                    new GrantUri(userId, uri, false));
7804            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7805                    new GrantUri(userId, uri, true));
7806
7807            final boolean exactValid = (exactPerm != null)
7808                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7809            final boolean prefixValid = (prefixPerm != null)
7810                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7811
7812            if (!(exactValid || prefixValid)) {
7813                throw new SecurityException("No persistable permission grants found for UID "
7814                        + callingUid + " and Uri " + grantUri.toSafeString());
7815            }
7816
7817            if (exactValid) {
7818                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7819            }
7820            if (prefixValid) {
7821                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7822            }
7823
7824            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7825
7826            if (persistChanged) {
7827                schedulePersistUriGrants();
7828            }
7829        }
7830    }
7831
7832    /**
7833     * @param uri This uri must NOT contain an embedded userId.
7834     * @param userId The userId in which the uri is to be resolved.
7835     */
7836    @Override
7837    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7838        enforceNotIsolatedCaller("releasePersistableUriPermission");
7839
7840        Preconditions.checkFlagsArgument(modeFlags,
7841                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7842
7843        synchronized (this) {
7844            final int callingUid = Binder.getCallingUid();
7845            boolean persistChanged = false;
7846
7847            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7848                    new GrantUri(userId, uri, false));
7849            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7850                    new GrantUri(userId, uri, true));
7851            if (exactPerm == null && prefixPerm == null) {
7852                throw new SecurityException("No permission grants found for UID " + callingUid
7853                        + " and Uri " + uri.toSafeString());
7854            }
7855
7856            if (exactPerm != null) {
7857                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7858                removeUriPermissionIfNeededLocked(exactPerm);
7859            }
7860            if (prefixPerm != null) {
7861                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7862                removeUriPermissionIfNeededLocked(prefixPerm);
7863            }
7864
7865            if (persistChanged) {
7866                schedulePersistUriGrants();
7867            }
7868        }
7869    }
7870
7871    /**
7872     * Prune any older {@link UriPermission} for the given UID until outstanding
7873     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7874     *
7875     * @return if any mutations occured that require persisting.
7876     */
7877    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7878        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7879        if (perms == null) return false;
7880        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7881
7882        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7883        for (UriPermission perm : perms.values()) {
7884            if (perm.persistedModeFlags != 0) {
7885                persisted.add(perm);
7886            }
7887        }
7888
7889        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7890        if (trimCount <= 0) return false;
7891
7892        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7893        for (int i = 0; i < trimCount; i++) {
7894            final UriPermission perm = persisted.get(i);
7895
7896            if (DEBUG_URI_PERMISSION) {
7897                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7898            }
7899
7900            perm.releasePersistableModes(~0);
7901            removeUriPermissionIfNeededLocked(perm);
7902        }
7903
7904        return true;
7905    }
7906
7907    @Override
7908    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7909            String packageName, boolean incoming) {
7910        enforceNotIsolatedCaller("getPersistedUriPermissions");
7911        Preconditions.checkNotNull(packageName, "packageName");
7912
7913        final int callingUid = Binder.getCallingUid();
7914        final IPackageManager pm = AppGlobals.getPackageManager();
7915        try {
7916            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7917            if (packageUid != callingUid) {
7918                throw new SecurityException(
7919                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7920            }
7921        } catch (RemoteException e) {
7922            throw new SecurityException("Failed to verify package name ownership");
7923        }
7924
7925        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7926        synchronized (this) {
7927            if (incoming) {
7928                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7929                        callingUid);
7930                if (perms == null) {
7931                    Slog.w(TAG, "No permission grants found for " + packageName);
7932                } else {
7933                    for (UriPermission perm : perms.values()) {
7934                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7935                            result.add(perm.buildPersistedPublicApiObject());
7936                        }
7937                    }
7938                }
7939            } else {
7940                final int size = mGrantedUriPermissions.size();
7941                for (int i = 0; i < size; i++) {
7942                    final ArrayMap<GrantUri, UriPermission> perms =
7943                            mGrantedUriPermissions.valueAt(i);
7944                    for (UriPermission perm : perms.values()) {
7945                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7946                            result.add(perm.buildPersistedPublicApiObject());
7947                        }
7948                    }
7949                }
7950            }
7951        }
7952        return new ParceledListSlice<android.content.UriPermission>(result);
7953    }
7954
7955    @Override
7956    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7957        synchronized (this) {
7958            ProcessRecord app =
7959                who != null ? getRecordForAppLocked(who) : null;
7960            if (app == null) return;
7961
7962            Message msg = Message.obtain();
7963            msg.what = WAIT_FOR_DEBUGGER_MSG;
7964            msg.obj = app;
7965            msg.arg1 = waiting ? 1 : 0;
7966            mHandler.sendMessage(msg);
7967        }
7968    }
7969
7970    @Override
7971    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7972        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7973        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7974        outInfo.availMem = Process.getFreeMemory();
7975        outInfo.totalMem = Process.getTotalMemory();
7976        outInfo.threshold = homeAppMem;
7977        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7978        outInfo.hiddenAppThreshold = cachedAppMem;
7979        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7980                ProcessList.SERVICE_ADJ);
7981        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7982                ProcessList.VISIBLE_APP_ADJ);
7983        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7984                ProcessList.FOREGROUND_APP_ADJ);
7985    }
7986
7987    // =========================================================
7988    // TASK MANAGEMENT
7989    // =========================================================
7990
7991    @Override
7992    public List<IAppTask> getAppTasks(String callingPackage) {
7993        int callingUid = Binder.getCallingUid();
7994        long ident = Binder.clearCallingIdentity();
7995
7996        synchronized(this) {
7997            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7998            try {
7999                if (localLOGV) Slog.v(TAG, "getAppTasks");
8000
8001                final int N = mRecentTasks.size();
8002                for (int i = 0; i < N; i++) {
8003                    TaskRecord tr = mRecentTasks.get(i);
8004                    // Skip tasks that do not match the caller.  We don't need to verify
8005                    // callingPackage, because we are also limiting to callingUid and know
8006                    // that will limit to the correct security sandbox.
8007                    if (tr.effectiveUid != callingUid) {
8008                        continue;
8009                    }
8010                    Intent intent = tr.getBaseIntent();
8011                    if (intent == null ||
8012                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8013                        continue;
8014                    }
8015                    ActivityManager.RecentTaskInfo taskInfo =
8016                            createRecentTaskInfoFromTaskRecord(tr);
8017                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8018                    list.add(taskImpl);
8019                }
8020            } finally {
8021                Binder.restoreCallingIdentity(ident);
8022            }
8023            return list;
8024        }
8025    }
8026
8027    @Override
8028    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8029        final int callingUid = Binder.getCallingUid();
8030        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8031
8032        synchronized(this) {
8033            if (localLOGV) Slog.v(
8034                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8035
8036            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8037                    callingUid);
8038
8039            // TODO: Improve with MRU list from all ActivityStacks.
8040            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8041        }
8042
8043        return list;
8044    }
8045
8046    /**
8047     * Creates a new RecentTaskInfo from a TaskRecord.
8048     */
8049    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8050        // Update the task description to reflect any changes in the task stack
8051        tr.updateTaskDescription();
8052
8053        // Compose the recent task info
8054        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8055        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8056        rti.persistentId = tr.taskId;
8057        rti.baseIntent = new Intent(tr.getBaseIntent());
8058        rti.origActivity = tr.origActivity;
8059        rti.description = tr.lastDescription;
8060        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8061        rti.userId = tr.userId;
8062        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8063        rti.firstActiveTime = tr.firstActiveTime;
8064        rti.lastActiveTime = tr.lastActiveTime;
8065        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8066        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8067        return rti;
8068    }
8069
8070    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8071        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8072                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8073        if (!allowed) {
8074            if (checkPermission(android.Manifest.permission.GET_TASKS,
8075                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8076                // Temporary compatibility: some existing apps on the system image may
8077                // still be requesting the old permission and not switched to the new
8078                // one; if so, we'll still allow them full access.  This means we need
8079                // to see if they are holding the old permission and are a system app.
8080                try {
8081                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8082                        allowed = true;
8083                        Slog.w(TAG, caller + ": caller " + callingUid
8084                                + " is using old GET_TASKS but privileged; allowing");
8085                    }
8086                } catch (RemoteException e) {
8087                }
8088            }
8089        }
8090        if (!allowed) {
8091            Slog.w(TAG, caller + ": caller " + callingUid
8092                    + " does not hold GET_TASKS; limiting output");
8093        }
8094        return allowed;
8095    }
8096
8097    @Override
8098    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8099        final int callingUid = Binder.getCallingUid();
8100        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8101                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8102
8103        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8104        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8105        synchronized (this) {
8106            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8107                    callingUid);
8108            final boolean detailed = checkCallingPermission(
8109                    android.Manifest.permission.GET_DETAILED_TASKS)
8110                    == PackageManager.PERMISSION_GRANTED;
8111
8112            final int N = mRecentTasks.size();
8113            ArrayList<ActivityManager.RecentTaskInfo> res
8114                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8115                            maxNum < N ? maxNum : N);
8116
8117            final Set<Integer> includedUsers;
8118            if (includeProfiles) {
8119                includedUsers = getProfileIdsLocked(userId);
8120            } else {
8121                includedUsers = new HashSet<Integer>();
8122            }
8123            includedUsers.add(Integer.valueOf(userId));
8124
8125            for (int i=0; i<N && maxNum > 0; i++) {
8126                TaskRecord tr = mRecentTasks.get(i);
8127                // Only add calling user or related users recent tasks
8128                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8129                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8130                    continue;
8131                }
8132
8133                // Return the entry if desired by the caller.  We always return
8134                // the first entry, because callers always expect this to be the
8135                // foreground app.  We may filter others if the caller has
8136                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8137                // we should exclude the entry.
8138
8139                if (i == 0
8140                        || withExcluded
8141                        || (tr.intent == null)
8142                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8143                                == 0)) {
8144                    if (!allowed) {
8145                        // If the caller doesn't have the GET_TASKS permission, then only
8146                        // allow them to see a small subset of tasks -- their own and home.
8147                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8148                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8149                            continue;
8150                        }
8151                    }
8152                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8153                        if (tr.stack != null && tr.stack.isHomeStack()) {
8154                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8155                            continue;
8156                        }
8157                    }
8158                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8159                        // Don't include auto remove tasks that are finished or finishing.
8160                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8161                                + tr);
8162                        continue;
8163                    }
8164                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8165                            && !tr.isAvailable) {
8166                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8167                        continue;
8168                    }
8169
8170                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8171                    if (!detailed) {
8172                        rti.baseIntent.replaceExtras((Bundle)null);
8173                    }
8174
8175                    res.add(rti);
8176                    maxNum--;
8177                }
8178            }
8179            return res;
8180        }
8181    }
8182
8183    private TaskRecord taskForIdLocked(int id) {
8184        final TaskRecord task = recentTaskForIdLocked(id);
8185        if (task != null) {
8186            return task;
8187        }
8188
8189        // Don't give up. Sometimes it just hasn't made it to recents yet.
8190        return mStackSupervisor.anyTaskForIdLocked(id);
8191    }
8192
8193    private TaskRecord recentTaskForIdLocked(int id) {
8194        final int N = mRecentTasks.size();
8195            for (int i=0; i<N; i++) {
8196                TaskRecord tr = mRecentTasks.get(i);
8197                if (tr.taskId == id) {
8198                    return tr;
8199                }
8200            }
8201            return null;
8202    }
8203
8204    @Override
8205    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8206        synchronized (this) {
8207            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8208                    "getTaskThumbnail()");
8209            TaskRecord tr = recentTaskForIdLocked(id);
8210            if (tr != null) {
8211                return tr.getTaskThumbnailLocked();
8212            }
8213        }
8214        return null;
8215    }
8216
8217    @Override
8218    public int addAppTask(IBinder activityToken, Intent intent,
8219            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8220        final int callingUid = Binder.getCallingUid();
8221        final long callingIdent = Binder.clearCallingIdentity();
8222
8223        try {
8224            synchronized (this) {
8225                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8226                if (r == null) {
8227                    throw new IllegalArgumentException("Activity does not exist; token="
8228                            + activityToken);
8229                }
8230                ComponentName comp = intent.getComponent();
8231                if (comp == null) {
8232                    throw new IllegalArgumentException("Intent " + intent
8233                            + " must specify explicit component");
8234                }
8235                if (thumbnail.getWidth() != mThumbnailWidth
8236                        || thumbnail.getHeight() != mThumbnailHeight) {
8237                    throw new IllegalArgumentException("Bad thumbnail size: got "
8238                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8239                            + mThumbnailWidth + "x" + mThumbnailHeight);
8240                }
8241                if (intent.getSelector() != null) {
8242                    intent.setSelector(null);
8243                }
8244                if (intent.getSourceBounds() != null) {
8245                    intent.setSourceBounds(null);
8246                }
8247                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8248                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8249                        // The caller has added this as an auto-remove task...  that makes no
8250                        // sense, so turn off auto-remove.
8251                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8252                    }
8253                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8254                    // Must be a new task.
8255                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8256                }
8257                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8258                    mLastAddedTaskActivity = null;
8259                }
8260                ActivityInfo ainfo = mLastAddedTaskActivity;
8261                if (ainfo == null) {
8262                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8263                            comp, 0, UserHandle.getUserId(callingUid));
8264                    if (ainfo.applicationInfo.uid != callingUid) {
8265                        throw new SecurityException(
8266                                "Can't add task for another application: target uid="
8267                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8268                    }
8269                }
8270
8271                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8272                        intent, description);
8273
8274                int trimIdx = trimRecentsForTaskLocked(task, false);
8275                if (trimIdx >= 0) {
8276                    // If this would have caused a trim, then we'll abort because that
8277                    // means it would be added at the end of the list but then just removed.
8278                    return INVALID_TASK_ID;
8279                }
8280
8281                final int N = mRecentTasks.size();
8282                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8283                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8284                    tr.removedFromRecents();
8285                }
8286
8287                task.inRecents = true;
8288                mRecentTasks.add(task);
8289                r.task.stack.addTask(task, false, false);
8290
8291                task.setLastThumbnail(thumbnail);
8292                task.freeLastThumbnail();
8293
8294                return task.taskId;
8295            }
8296        } finally {
8297            Binder.restoreCallingIdentity(callingIdent);
8298        }
8299    }
8300
8301    @Override
8302    public Point getAppTaskThumbnailSize() {
8303        synchronized (this) {
8304            return new Point(mThumbnailWidth,  mThumbnailHeight);
8305        }
8306    }
8307
8308    @Override
8309    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8310        synchronized (this) {
8311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8312            if (r != null) {
8313                r.setTaskDescription(td);
8314                r.task.updateTaskDescription();
8315            }
8316        }
8317    }
8318
8319    @Override
8320    public Bitmap getTaskDescriptionIcon(String filename) {
8321        if (!FileUtils.isValidExtFilename(filename)
8322                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8323            throw new IllegalArgumentException("Bad filename: " + filename);
8324        }
8325        return mTaskPersister.getTaskDescriptionIcon(filename);
8326    }
8327
8328    @Override
8329    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8330            throws RemoteException {
8331        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8332                opts.getCustomInPlaceResId() == 0) {
8333            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8334                    "with valid animation");
8335        }
8336        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8337        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8338                opts.getCustomInPlaceResId());
8339        mWindowManager.executeAppTransition();
8340    }
8341
8342    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8343        mRecentTasks.remove(tr);
8344        tr.removedFromRecents();
8345        ComponentName component = tr.getBaseIntent().getComponent();
8346        if (component == null) {
8347            Slog.w(TAG, "No component for base intent of task: " + tr);
8348            return;
8349        }
8350
8351        if (!killProcess) {
8352            return;
8353        }
8354
8355        // Determine if the process(es) for this task should be killed.
8356        final String pkg = component.getPackageName();
8357        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8358        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8359        for (int i = 0; i < pmap.size(); i++) {
8360
8361            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8362            for (int j = 0; j < uids.size(); j++) {
8363                ProcessRecord proc = uids.valueAt(j);
8364                if (proc.userId != tr.userId) {
8365                    // Don't kill process for a different user.
8366                    continue;
8367                }
8368                if (proc == mHomeProcess) {
8369                    // Don't kill the home process along with tasks from the same package.
8370                    continue;
8371                }
8372                if (!proc.pkgList.containsKey(pkg)) {
8373                    // Don't kill process that is not associated with this task.
8374                    continue;
8375                }
8376
8377                for (int k = 0; k < proc.activities.size(); k++) {
8378                    TaskRecord otherTask = proc.activities.get(k).task;
8379                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8380                        // Don't kill process(es) that has an activity in a different task that is
8381                        // also in recents.
8382                        return;
8383                    }
8384                }
8385
8386                // Add process to kill list.
8387                procsToKill.add(proc);
8388            }
8389        }
8390
8391        // Find any running services associated with this app and stop if needed.
8392        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8393
8394        // Kill the running processes.
8395        for (int i = 0; i < procsToKill.size(); i++) {
8396            ProcessRecord pr = procsToKill.get(i);
8397            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8398                pr.kill("remove task", true);
8399            } else {
8400                pr.waitingToKill = "remove task";
8401            }
8402        }
8403    }
8404
8405    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8406        // Remove all tasks with activities in the specified package from the list of recent tasks
8407        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8408            TaskRecord tr = mRecentTasks.get(i);
8409            if (tr.userId != userId) continue;
8410
8411            ComponentName cn = tr.intent.getComponent();
8412            if (cn != null && cn.getPackageName().equals(packageName)) {
8413                // If the package name matches, remove the task.
8414                removeTaskByIdLocked(tr.taskId, true);
8415            }
8416        }
8417    }
8418
8419    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8420        final IPackageManager pm = AppGlobals.getPackageManager();
8421        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8422
8423        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8424            TaskRecord tr = mRecentTasks.get(i);
8425            if (tr.userId != userId) continue;
8426
8427            ComponentName cn = tr.intent.getComponent();
8428            if (cn != null && cn.getPackageName().equals(packageName)) {
8429                // Skip if component still exists in the package.
8430                if (componentsKnownToExist.contains(cn)) continue;
8431
8432                try {
8433                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8434                    if (info != null) {
8435                        componentsKnownToExist.add(cn);
8436                    } else {
8437                        removeTaskByIdLocked(tr.taskId, false);
8438                    }
8439                } catch (RemoteException e) {
8440                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8441                }
8442            }
8443        }
8444    }
8445
8446    /**
8447     * Removes the task with the specified task id.
8448     *
8449     * @param taskId Identifier of the task to be removed.
8450     * @param killProcess Kill any process associated with the task if possible.
8451     * @return Returns true if the given task was found and removed.
8452     */
8453    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8454        TaskRecord tr = taskForIdLocked(taskId);
8455        if (tr != null) {
8456            tr.removeTaskActivitiesLocked();
8457            cleanUpRemovedTaskLocked(tr, killProcess);
8458            if (tr.isPersistable) {
8459                notifyTaskPersisterLocked(null, true);
8460            }
8461            return true;
8462        }
8463        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8464        return false;
8465    }
8466
8467    @Override
8468    public boolean removeTask(int taskId) {
8469        synchronized (this) {
8470            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8471                    "removeTask()");
8472            long ident = Binder.clearCallingIdentity();
8473            try {
8474                return removeTaskByIdLocked(taskId, true);
8475            } finally {
8476                Binder.restoreCallingIdentity(ident);
8477            }
8478        }
8479    }
8480
8481    /**
8482     * TODO: Add mController hook
8483     */
8484    @Override
8485    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8486        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8487                "moveTaskToFront()");
8488
8489        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8490        synchronized(this) {
8491            moveTaskToFrontLocked(taskId, flags, options);
8492        }
8493    }
8494
8495    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8496        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8497                Binder.getCallingUid(), -1, -1, "Task to front")) {
8498            ActivityOptions.abort(options);
8499            return;
8500        }
8501        final long origId = Binder.clearCallingIdentity();
8502        try {
8503            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8504            if (task == null) {
8505                Slog.d(TAG, "Could not find task for id: "+ taskId);
8506                return;
8507            }
8508            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8509                mStackSupervisor.showLockTaskToast();
8510                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8511                return;
8512            }
8513            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8514            if (prev != null && prev.isRecentsActivity()) {
8515                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8516            }
8517            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8518        } finally {
8519            Binder.restoreCallingIdentity(origId);
8520        }
8521        ActivityOptions.abort(options);
8522    }
8523
8524    @Override
8525    public void moveTaskToBack(int taskId) {
8526        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8527                "moveTaskToBack()");
8528
8529        synchronized(this) {
8530            TaskRecord tr = taskForIdLocked(taskId);
8531            if (tr != null) {
8532                if (tr == mStackSupervisor.mLockTaskModeTask) {
8533                    mStackSupervisor.showLockTaskToast();
8534                    return;
8535                }
8536                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8537                ActivityStack stack = tr.stack;
8538                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8539                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8540                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8541                        return;
8542                    }
8543                }
8544                final long origId = Binder.clearCallingIdentity();
8545                try {
8546                    stack.moveTaskToBackLocked(taskId, null);
8547                } finally {
8548                    Binder.restoreCallingIdentity(origId);
8549                }
8550            }
8551        }
8552    }
8553
8554    /**
8555     * Moves an activity, and all of the other activities within the same task, to the bottom
8556     * of the history stack.  The activity's order within the task is unchanged.
8557     *
8558     * @param token A reference to the activity we wish to move
8559     * @param nonRoot If false then this only works if the activity is the root
8560     *                of a task; if true it will work for any activity in a task.
8561     * @return Returns true if the move completed, false if not.
8562     */
8563    @Override
8564    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8565        enforceNotIsolatedCaller("moveActivityTaskToBack");
8566        synchronized(this) {
8567            final long origId = Binder.clearCallingIdentity();
8568            try {
8569                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8570                if (taskId >= 0) {
8571                    if ((mStackSupervisor.mLockTaskModeTask != null)
8572                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8573                        mStackSupervisor.showLockTaskToast();
8574                        return false;
8575                    }
8576                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8577                }
8578            } finally {
8579                Binder.restoreCallingIdentity(origId);
8580            }
8581        }
8582        return false;
8583    }
8584
8585    @Override
8586    public void moveTaskBackwards(int task) {
8587        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8588                "moveTaskBackwards()");
8589
8590        synchronized(this) {
8591            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8592                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8593                return;
8594            }
8595            final long origId = Binder.clearCallingIdentity();
8596            moveTaskBackwardsLocked(task);
8597            Binder.restoreCallingIdentity(origId);
8598        }
8599    }
8600
8601    private final void moveTaskBackwardsLocked(int task) {
8602        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8603    }
8604
8605    @Override
8606    public IBinder getHomeActivityToken() throws RemoteException {
8607        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8608                "getHomeActivityToken()");
8609        synchronized (this) {
8610            return mStackSupervisor.getHomeActivityToken();
8611        }
8612    }
8613
8614    @Override
8615    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8616            IActivityContainerCallback callback) throws RemoteException {
8617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8618                "createActivityContainer()");
8619        synchronized (this) {
8620            if (parentActivityToken == null) {
8621                throw new IllegalArgumentException("parent token must not be null");
8622            }
8623            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8624            if (r == null) {
8625                return null;
8626            }
8627            if (callback == null) {
8628                throw new IllegalArgumentException("callback must not be null");
8629            }
8630            return mStackSupervisor.createActivityContainer(r, callback);
8631        }
8632    }
8633
8634    @Override
8635    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8637                "deleteActivityContainer()");
8638        synchronized (this) {
8639            mStackSupervisor.deleteActivityContainer(container);
8640        }
8641    }
8642
8643    @Override
8644    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8645            throws RemoteException {
8646        synchronized (this) {
8647            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8648            if (stack != null) {
8649                return stack.mActivityContainer;
8650            }
8651            return null;
8652        }
8653    }
8654
8655    @Override
8656    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8658                "moveTaskToStack()");
8659        if (stackId == HOME_STACK_ID) {
8660            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8661                    new RuntimeException("here").fillInStackTrace());
8662        }
8663        synchronized (this) {
8664            long ident = Binder.clearCallingIdentity();
8665            try {
8666                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8667                        + stackId + " toTop=" + toTop);
8668                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8669            } finally {
8670                Binder.restoreCallingIdentity(ident);
8671            }
8672        }
8673    }
8674
8675    @Override
8676    public void resizeStack(int stackBoxId, Rect bounds) {
8677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8678                "resizeStackBox()");
8679        long ident = Binder.clearCallingIdentity();
8680        try {
8681            mWindowManager.resizeStack(stackBoxId, bounds);
8682        } finally {
8683            Binder.restoreCallingIdentity(ident);
8684        }
8685    }
8686
8687    @Override
8688    public List<StackInfo> getAllStackInfos() {
8689        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8690                "getAllStackInfos()");
8691        long ident = Binder.clearCallingIdentity();
8692        try {
8693            synchronized (this) {
8694                return mStackSupervisor.getAllStackInfosLocked();
8695            }
8696        } finally {
8697            Binder.restoreCallingIdentity(ident);
8698        }
8699    }
8700
8701    @Override
8702    public StackInfo getStackInfo(int stackId) {
8703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8704                "getStackInfo()");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            synchronized (this) {
8708                return mStackSupervisor.getStackInfoLocked(stackId);
8709            }
8710        } finally {
8711            Binder.restoreCallingIdentity(ident);
8712        }
8713    }
8714
8715    @Override
8716    public boolean isInHomeStack(int taskId) {
8717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8718                "getStackInfo()");
8719        long ident = Binder.clearCallingIdentity();
8720        try {
8721            synchronized (this) {
8722                TaskRecord tr = taskForIdLocked(taskId);
8723                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8724            }
8725        } finally {
8726            Binder.restoreCallingIdentity(ident);
8727        }
8728    }
8729
8730    @Override
8731    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8732        synchronized(this) {
8733            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8734        }
8735    }
8736
8737    private boolean isLockTaskAuthorized(String pkg) {
8738        final DevicePolicyManager dpm = (DevicePolicyManager)
8739                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8740        try {
8741            int uid = mContext.getPackageManager().getPackageUid(pkg,
8742                    Binder.getCallingUserHandle().getIdentifier());
8743            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8744        } catch (NameNotFoundException e) {
8745            return false;
8746        }
8747    }
8748
8749    void startLockTaskMode(TaskRecord task) {
8750        final String pkg;
8751        synchronized (this) {
8752            pkg = task.intent.getComponent().getPackageName();
8753        }
8754        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8755        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8756            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8757                    StatusBarManagerInternal.class);
8758            if (statusBarManager != null) {
8759                statusBarManager.showScreenPinningRequest();
8760            }
8761            return;
8762        }
8763        long ident = Binder.clearCallingIdentity();
8764        try {
8765            synchronized (this) {
8766                // Since we lost lock on task, make sure it is still there.
8767                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8768                if (task != null) {
8769                    if (!isSystemInitiated
8770                            && ((mStackSupervisor.getFocusedStack() == null)
8771                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8772                        throw new IllegalArgumentException("Invalid task, not in foreground");
8773                    }
8774                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8775                }
8776            }
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public void startLockTaskMode(int taskId) {
8784        final TaskRecord task;
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793        if (task != null) {
8794            startLockTaskMode(task);
8795        }
8796    }
8797
8798    @Override
8799    public void startLockTaskMode(IBinder token) {
8800        final TaskRecord task;
8801        long ident = Binder.clearCallingIdentity();
8802        try {
8803            synchronized (this) {
8804                final ActivityRecord r = ActivityRecord.forToken(token);
8805                if (r == null) {
8806                    return;
8807                }
8808                task = r.task;
8809            }
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813        if (task != null) {
8814            startLockTaskMode(task);
8815        }
8816    }
8817
8818    @Override
8819    public void startLockTaskModeOnCurrent() throws RemoteException {
8820        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8821                "startLockTaskModeOnCurrent");
8822        long ident = Binder.clearCallingIdentity();
8823        try {
8824            ActivityRecord r = null;
8825            synchronized (this) {
8826                r = mStackSupervisor.topRunningActivityLocked();
8827            }
8828            startLockTaskMode(r.task);
8829        } finally {
8830            Binder.restoreCallingIdentity(ident);
8831        }
8832    }
8833
8834    @Override
8835    public void stopLockTaskMode() {
8836        // Verify that the user matches the package of the intent for the TaskRecord
8837        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8838        // and stopLockTaskMode.
8839        final int callingUid = Binder.getCallingUid();
8840        if (callingUid != Process.SYSTEM_UID) {
8841            try {
8842                String pkg =
8843                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8844                int uid = mContext.getPackageManager().getPackageUid(pkg,
8845                        Binder.getCallingUserHandle().getIdentifier());
8846                if (uid != callingUid) {
8847                    throw new SecurityException("Invalid uid, expected " + uid);
8848                }
8849            } catch (NameNotFoundException e) {
8850                Log.d(TAG, "stopLockTaskMode " + e);
8851                return;
8852            }
8853        }
8854        long ident = Binder.clearCallingIdentity();
8855        try {
8856            Log.d(TAG, "stopLockTaskMode");
8857            // Stop lock task
8858            synchronized (this) {
8859                mStackSupervisor.setLockTaskModeLocked(null, false);
8860            }
8861        } finally {
8862            Binder.restoreCallingIdentity(ident);
8863        }
8864    }
8865
8866    @Override
8867    public void stopLockTaskModeOnCurrent() throws RemoteException {
8868        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8869                "stopLockTaskModeOnCurrent");
8870        long ident = Binder.clearCallingIdentity();
8871        try {
8872            stopLockTaskMode();
8873        } finally {
8874            Binder.restoreCallingIdentity(ident);
8875        }
8876    }
8877
8878    @Override
8879    public boolean isInLockTaskMode() {
8880        synchronized (this) {
8881            return mStackSupervisor.isInLockTaskMode();
8882        }
8883    }
8884
8885    // =========================================================
8886    // CONTENT PROVIDERS
8887    // =========================================================
8888
8889    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8890        List<ProviderInfo> providers = null;
8891        try {
8892            providers = AppGlobals.getPackageManager().
8893                queryContentProviders(app.processName, app.uid,
8894                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8895        } catch (RemoteException ex) {
8896        }
8897        if (DEBUG_MU)
8898            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8899        int userId = app.userId;
8900        if (providers != null) {
8901            int N = providers.size();
8902            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8903            for (int i=0; i<N; i++) {
8904                ProviderInfo cpi =
8905                    (ProviderInfo)providers.get(i);
8906                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8907                        cpi.name, cpi.flags);
8908                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8909                    // This is a singleton provider, but a user besides the
8910                    // default user is asking to initialize a process it runs
8911                    // in...  well, no, it doesn't actually run in this process,
8912                    // it runs in the process of the default user.  Get rid of it.
8913                    providers.remove(i);
8914                    N--;
8915                    i--;
8916                    continue;
8917                }
8918
8919                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8920                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8921                if (cpr == null) {
8922                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8923                    mProviderMap.putProviderByClass(comp, cpr);
8924                }
8925                if (DEBUG_MU)
8926                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8927                app.pubProviders.put(cpi.name, cpr);
8928                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8929                    // Don't add this if it is a platform component that is marked
8930                    // to run in multiple processes, because this is actually
8931                    // part of the framework so doesn't make sense to track as a
8932                    // separate apk in the process.
8933                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8934                            mProcessStats);
8935                }
8936                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8937            }
8938        }
8939        return providers;
8940    }
8941
8942    /**
8943     * Check if {@link ProcessRecord} has a possible chance at accessing the
8944     * given {@link ProviderInfo}. Final permission checking is always done
8945     * in {@link ContentProvider}.
8946     */
8947    private final String checkContentProviderPermissionLocked(
8948            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8949        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8950        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8951        boolean checkedGrants = false;
8952        if (checkUser) {
8953            // Looking for cross-user grants before enforcing the typical cross-users permissions
8954            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8955            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8956                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8957                    return null;
8958                }
8959                checkedGrants = true;
8960            }
8961            userId = handleIncomingUser(callingPid, callingUid, userId,
8962                    false, ALLOW_NON_FULL,
8963                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8964            if (userId != tmpTargetUserId) {
8965                // When we actually went to determine the final targer user ID, this ended
8966                // up different than our initial check for the authority.  This is because
8967                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8968                // SELF.  So we need to re-check the grants again.
8969                checkedGrants = false;
8970            }
8971        }
8972        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8973                cpi.applicationInfo.uid, cpi.exported)
8974                == PackageManager.PERMISSION_GRANTED) {
8975            return null;
8976        }
8977        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8978                cpi.applicationInfo.uid, cpi.exported)
8979                == PackageManager.PERMISSION_GRANTED) {
8980            return null;
8981        }
8982
8983        PathPermission[] pps = cpi.pathPermissions;
8984        if (pps != null) {
8985            int i = pps.length;
8986            while (i > 0) {
8987                i--;
8988                PathPermission pp = pps[i];
8989                String pprperm = pp.getReadPermission();
8990                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8991                        cpi.applicationInfo.uid, cpi.exported)
8992                        == PackageManager.PERMISSION_GRANTED) {
8993                    return null;
8994                }
8995                String ppwperm = pp.getWritePermission();
8996                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8997                        cpi.applicationInfo.uid, cpi.exported)
8998                        == PackageManager.PERMISSION_GRANTED) {
8999                    return null;
9000                }
9001            }
9002        }
9003        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9004            return null;
9005        }
9006
9007        String msg;
9008        if (!cpi.exported) {
9009            msg = "Permission Denial: opening provider " + cpi.name
9010                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9011                    + ", uid=" + callingUid + ") that is not exported from uid "
9012                    + cpi.applicationInfo.uid;
9013        } else {
9014            msg = "Permission Denial: opening provider " + cpi.name
9015                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9016                    + ", uid=" + callingUid + ") requires "
9017                    + cpi.readPermission + " or " + cpi.writePermission;
9018        }
9019        Slog.w(TAG, msg);
9020        return msg;
9021    }
9022
9023    /**
9024     * Returns if the ContentProvider has granted a uri to callingUid
9025     */
9026    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9027        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9028        if (perms != null) {
9029            for (int i=perms.size()-1; i>=0; i--) {
9030                GrantUri grantUri = perms.keyAt(i);
9031                if (grantUri.sourceUserId == userId || !checkUser) {
9032                    if (matchesProvider(grantUri.uri, cpi)) {
9033                        return true;
9034                    }
9035                }
9036            }
9037        }
9038        return false;
9039    }
9040
9041    /**
9042     * Returns true if the uri authority is one of the authorities specified in the provider.
9043     */
9044    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9045        String uriAuth = uri.getAuthority();
9046        String cpiAuth = cpi.authority;
9047        if (cpiAuth.indexOf(';') == -1) {
9048            return cpiAuth.equals(uriAuth);
9049        }
9050        String[] cpiAuths = cpiAuth.split(";");
9051        int length = cpiAuths.length;
9052        for (int i = 0; i < length; i++) {
9053            if (cpiAuths[i].equals(uriAuth)) return true;
9054        }
9055        return false;
9056    }
9057
9058    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9059            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9060        if (r != null) {
9061            for (int i=0; i<r.conProviders.size(); i++) {
9062                ContentProviderConnection conn = r.conProviders.get(i);
9063                if (conn.provider == cpr) {
9064                    if (DEBUG_PROVIDER) Slog.v(TAG,
9065                            "Adding provider requested by "
9066                            + r.processName + " from process "
9067                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9068                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9069                    if (stable) {
9070                        conn.stableCount++;
9071                        conn.numStableIncs++;
9072                    } else {
9073                        conn.unstableCount++;
9074                        conn.numUnstableIncs++;
9075                    }
9076                    return conn;
9077                }
9078            }
9079            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9080            if (stable) {
9081                conn.stableCount = 1;
9082                conn.numStableIncs = 1;
9083            } else {
9084                conn.unstableCount = 1;
9085                conn.numUnstableIncs = 1;
9086            }
9087            cpr.connections.add(conn);
9088            r.conProviders.add(conn);
9089            return conn;
9090        }
9091        cpr.addExternalProcessHandleLocked(externalProcessToken);
9092        return null;
9093    }
9094
9095    boolean decProviderCountLocked(ContentProviderConnection conn,
9096            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9097        if (conn != null) {
9098            cpr = conn.provider;
9099            if (DEBUG_PROVIDER) Slog.v(TAG,
9100                    "Removing provider requested by "
9101                    + conn.client.processName + " from process "
9102                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9103                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9104            if (stable) {
9105                conn.stableCount--;
9106            } else {
9107                conn.unstableCount--;
9108            }
9109            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9110                cpr.connections.remove(conn);
9111                conn.client.conProviders.remove(conn);
9112                return true;
9113            }
9114            return false;
9115        }
9116        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9117        return false;
9118    }
9119
9120    private void checkTime(long startTime, String where) {
9121        long now = SystemClock.elapsedRealtime();
9122        if ((now-startTime) > 1000) {
9123            // If we are taking more than a second, log about it.
9124            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9125        }
9126    }
9127
9128    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9129            String name, IBinder token, boolean stable, int userId) {
9130        ContentProviderRecord cpr;
9131        ContentProviderConnection conn = null;
9132        ProviderInfo cpi = null;
9133
9134        synchronized(this) {
9135            long startTime = SystemClock.elapsedRealtime();
9136
9137            ProcessRecord r = null;
9138            if (caller != null) {
9139                r = getRecordForAppLocked(caller);
9140                if (r == null) {
9141                    throw new SecurityException(
9142                            "Unable to find app for caller " + caller
9143                          + " (pid=" + Binder.getCallingPid()
9144                          + ") when getting content provider " + name);
9145                }
9146            }
9147
9148            boolean checkCrossUser = true;
9149
9150            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9151
9152            // First check if this content provider has been published...
9153            cpr = mProviderMap.getProviderByName(name, userId);
9154            // If that didn't work, check if it exists for user 0 and then
9155            // verify that it's a singleton provider before using it.
9156            if (cpr == null && userId != UserHandle.USER_OWNER) {
9157                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9158                if (cpr != null) {
9159                    cpi = cpr.info;
9160                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9161                            cpi.name, cpi.flags)
9162                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9163                        userId = UserHandle.USER_OWNER;
9164                        checkCrossUser = false;
9165                    } else {
9166                        cpr = null;
9167                        cpi = null;
9168                    }
9169                }
9170            }
9171
9172            boolean providerRunning = cpr != null;
9173            if (providerRunning) {
9174                cpi = cpr.info;
9175                String msg;
9176                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9177                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9178                        != null) {
9179                    throw new SecurityException(msg);
9180                }
9181                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9182
9183                if (r != null && cpr.canRunHere(r)) {
9184                    // This provider has been published or is in the process
9185                    // of being published...  but it is also allowed to run
9186                    // in the caller's process, so don't make a connection
9187                    // and just let the caller instantiate its own instance.
9188                    ContentProviderHolder holder = cpr.newHolder(null);
9189                    // don't give caller the provider object, it needs
9190                    // to make its own.
9191                    holder.provider = null;
9192                    return holder;
9193                }
9194
9195                final long origId = Binder.clearCallingIdentity();
9196
9197                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9198
9199                // In this case the provider instance already exists, so we can
9200                // return it right away.
9201                conn = incProviderCountLocked(r, cpr, token, stable);
9202                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9203                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9204                        // If this is a perceptible app accessing the provider,
9205                        // make sure to count it as being accessed and thus
9206                        // back up on the LRU list.  This is good because
9207                        // content providers are often expensive to start.
9208                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9209                        updateLruProcessLocked(cpr.proc, false, null);
9210                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9211                    }
9212                }
9213
9214                if (cpr.proc != null) {
9215                    if (false) {
9216                        if (cpr.name.flattenToShortString().equals(
9217                                "com.android.providers.calendar/.CalendarProvider2")) {
9218                            Slog.v(TAG, "****************** KILLING "
9219                                + cpr.name.flattenToShortString());
9220                            Process.killProcess(cpr.proc.pid);
9221                        }
9222                    }
9223                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9224                    boolean success = updateOomAdjLocked(cpr.proc);
9225                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9226                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9227                    // NOTE: there is still a race here where a signal could be
9228                    // pending on the process even though we managed to update its
9229                    // adj level.  Not sure what to do about this, but at least
9230                    // the race is now smaller.
9231                    if (!success) {
9232                        // Uh oh...  it looks like the provider's process
9233                        // has been killed on us.  We need to wait for a new
9234                        // process to be started, and make sure its death
9235                        // doesn't kill our process.
9236                        Slog.i(TAG,
9237                                "Existing provider " + cpr.name.flattenToShortString()
9238                                + " is crashing; detaching " + r);
9239                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9240                        checkTime(startTime, "getContentProviderImpl: before appDied");
9241                        appDiedLocked(cpr.proc);
9242                        checkTime(startTime, "getContentProviderImpl: after appDied");
9243                        if (!lastRef) {
9244                            // This wasn't the last ref our process had on
9245                            // the provider...  we have now been killed, bail.
9246                            return null;
9247                        }
9248                        providerRunning = false;
9249                        conn = null;
9250                    }
9251                }
9252
9253                Binder.restoreCallingIdentity(origId);
9254            }
9255
9256            boolean singleton;
9257            if (!providerRunning) {
9258                try {
9259                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9260                    cpi = AppGlobals.getPackageManager().
9261                        resolveContentProvider(name,
9262                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9263                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9264                } catch (RemoteException ex) {
9265                }
9266                if (cpi == null) {
9267                    return null;
9268                }
9269                // If the provider is a singleton AND
9270                // (it's a call within the same user || the provider is a
9271                // privileged app)
9272                // Then allow connecting to the singleton provider
9273                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9274                        cpi.name, cpi.flags)
9275                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9276                if (singleton) {
9277                    userId = UserHandle.USER_OWNER;
9278                }
9279                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9280                checkTime(startTime, "getContentProviderImpl: got app info for user");
9281
9282                String msg;
9283                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9284                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9285                        != null) {
9286                    throw new SecurityException(msg);
9287                }
9288                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9289
9290                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9291                        && !cpi.processName.equals("system")) {
9292                    // If this content provider does not run in the system
9293                    // process, and the system is not yet ready to run other
9294                    // processes, then fail fast instead of hanging.
9295                    throw new IllegalArgumentException(
9296                            "Attempt to launch content provider before system ready");
9297                }
9298
9299                // Make sure that the user who owns this provider is running.  If not,
9300                // we don't want to allow it to run.
9301                if (!isUserRunningLocked(userId, false)) {
9302                    Slog.w(TAG, "Unable to launch app "
9303                            + cpi.applicationInfo.packageName + "/"
9304                            + cpi.applicationInfo.uid + " for provider "
9305                            + name + ": user " + userId + " is stopped");
9306                    return null;
9307                }
9308
9309                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9310                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9311                cpr = mProviderMap.getProviderByClass(comp, userId);
9312                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9313                final boolean firstClass = cpr == null;
9314                if (firstClass) {
9315                    final long ident = Binder.clearCallingIdentity();
9316                    try {
9317                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9318                        ApplicationInfo ai =
9319                            AppGlobals.getPackageManager().
9320                                getApplicationInfo(
9321                                        cpi.applicationInfo.packageName,
9322                                        STOCK_PM_FLAGS, userId);
9323                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9324                        if (ai == null) {
9325                            Slog.w(TAG, "No package info for content provider "
9326                                    + cpi.name);
9327                            return null;
9328                        }
9329                        ai = getAppInfoForUser(ai, userId);
9330                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9331                    } catch (RemoteException ex) {
9332                        // pm is in same process, this will never happen.
9333                    } finally {
9334                        Binder.restoreCallingIdentity(ident);
9335                    }
9336                }
9337
9338                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9339
9340                if (r != null && cpr.canRunHere(r)) {
9341                    // If this is a multiprocess provider, then just return its
9342                    // info and allow the caller to instantiate it.  Only do
9343                    // this if the provider is the same user as the caller's
9344                    // process, or can run as root (so can be in any process).
9345                    return cpr.newHolder(null);
9346                }
9347
9348                if (DEBUG_PROVIDER) {
9349                    RuntimeException e = new RuntimeException("here");
9350                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9351                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9352                }
9353
9354                // This is single process, and our app is now connecting to it.
9355                // See if we are already in the process of launching this
9356                // provider.
9357                final int N = mLaunchingProviders.size();
9358                int i;
9359                for (i=0; i<N; i++) {
9360                    if (mLaunchingProviders.get(i) == cpr) {
9361                        break;
9362                    }
9363                }
9364
9365                // If the provider is not already being launched, then get it
9366                // started.
9367                if (i >= N) {
9368                    final long origId = Binder.clearCallingIdentity();
9369
9370                    try {
9371                        // Content provider is now in use, its package can't be stopped.
9372                        try {
9373                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9374                            AppGlobals.getPackageManager().setPackageStoppedState(
9375                                    cpr.appInfo.packageName, false, userId);
9376                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9377                        } catch (RemoteException e) {
9378                        } catch (IllegalArgumentException e) {
9379                            Slog.w(TAG, "Failed trying to unstop package "
9380                                    + cpr.appInfo.packageName + ": " + e);
9381                        }
9382
9383                        // Use existing process if already started
9384                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9385                        ProcessRecord proc = getProcessRecordLocked(
9386                                cpi.processName, cpr.appInfo.uid, false);
9387                        if (proc != null && proc.thread != null) {
9388                            if (DEBUG_PROVIDER) {
9389                                Slog.d(TAG, "Installing in existing process " + proc);
9390                            }
9391                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9392                            proc.pubProviders.put(cpi.name, cpr);
9393                            try {
9394                                proc.thread.scheduleInstallProvider(cpi);
9395                            } catch (RemoteException e) {
9396                            }
9397                        } else {
9398                            checkTime(startTime, "getContentProviderImpl: before start process");
9399                            proc = startProcessLocked(cpi.processName,
9400                                    cpr.appInfo, false, 0, "content provider",
9401                                    new ComponentName(cpi.applicationInfo.packageName,
9402                                            cpi.name), false, false, false);
9403                            checkTime(startTime, "getContentProviderImpl: after start process");
9404                            if (proc == null) {
9405                                Slog.w(TAG, "Unable to launch app "
9406                                        + cpi.applicationInfo.packageName + "/"
9407                                        + cpi.applicationInfo.uid + " for provider "
9408                                        + name + ": process is bad");
9409                                return null;
9410                            }
9411                        }
9412                        cpr.launchingApp = proc;
9413                        mLaunchingProviders.add(cpr);
9414                    } finally {
9415                        Binder.restoreCallingIdentity(origId);
9416                    }
9417                }
9418
9419                checkTime(startTime, "getContentProviderImpl: updating data structures");
9420
9421                // Make sure the provider is published (the same provider class
9422                // may be published under multiple names).
9423                if (firstClass) {
9424                    mProviderMap.putProviderByClass(comp, cpr);
9425                }
9426
9427                mProviderMap.putProviderByName(name, cpr);
9428                conn = incProviderCountLocked(r, cpr, token, stable);
9429                if (conn != null) {
9430                    conn.waiting = true;
9431                }
9432            }
9433            checkTime(startTime, "getContentProviderImpl: done!");
9434        }
9435
9436        // Wait for the provider to be published...
9437        synchronized (cpr) {
9438            while (cpr.provider == null) {
9439                if (cpr.launchingApp == null) {
9440                    Slog.w(TAG, "Unable to launch app "
9441                            + cpi.applicationInfo.packageName + "/"
9442                            + cpi.applicationInfo.uid + " for provider "
9443                            + name + ": launching app became null");
9444                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9445                            UserHandle.getUserId(cpi.applicationInfo.uid),
9446                            cpi.applicationInfo.packageName,
9447                            cpi.applicationInfo.uid, name);
9448                    return null;
9449                }
9450                try {
9451                    if (DEBUG_MU) {
9452                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9453                                + cpr.launchingApp);
9454                    }
9455                    if (conn != null) {
9456                        conn.waiting = true;
9457                    }
9458                    cpr.wait();
9459                } catch (InterruptedException ex) {
9460                } finally {
9461                    if (conn != null) {
9462                        conn.waiting = false;
9463                    }
9464                }
9465            }
9466        }
9467        return cpr != null ? cpr.newHolder(conn) : null;
9468    }
9469
9470    @Override
9471    public final ContentProviderHolder getContentProvider(
9472            IApplicationThread caller, String name, int userId, boolean stable) {
9473        enforceNotIsolatedCaller("getContentProvider");
9474        if (caller == null) {
9475            String msg = "null IApplicationThread when getting content provider "
9476                    + name;
9477            Slog.w(TAG, msg);
9478            throw new SecurityException(msg);
9479        }
9480        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9481        // with cross-user grant.
9482        return getContentProviderImpl(caller, name, null, stable, userId);
9483    }
9484
9485    public ContentProviderHolder getContentProviderExternal(
9486            String name, int userId, IBinder token) {
9487        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9488            "Do not have permission in call getContentProviderExternal()");
9489        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9490                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9491        return getContentProviderExternalUnchecked(name, token, userId);
9492    }
9493
9494    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9495            IBinder token, int userId) {
9496        return getContentProviderImpl(null, name, token, true, userId);
9497    }
9498
9499    /**
9500     * Drop a content provider from a ProcessRecord's bookkeeping
9501     */
9502    public void removeContentProvider(IBinder connection, boolean stable) {
9503        enforceNotIsolatedCaller("removeContentProvider");
9504        long ident = Binder.clearCallingIdentity();
9505        try {
9506            synchronized (this) {
9507                ContentProviderConnection conn;
9508                try {
9509                    conn = (ContentProviderConnection)connection;
9510                } catch (ClassCastException e) {
9511                    String msg ="removeContentProvider: " + connection
9512                            + " not a ContentProviderConnection";
9513                    Slog.w(TAG, msg);
9514                    throw new IllegalArgumentException(msg);
9515                }
9516                if (conn == null) {
9517                    throw new NullPointerException("connection is null");
9518                }
9519                if (decProviderCountLocked(conn, null, null, stable)) {
9520                    updateOomAdjLocked();
9521                }
9522            }
9523        } finally {
9524            Binder.restoreCallingIdentity(ident);
9525        }
9526    }
9527
9528    public void removeContentProviderExternal(String name, IBinder token) {
9529        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9530            "Do not have permission in call removeContentProviderExternal()");
9531        int userId = UserHandle.getCallingUserId();
9532        long ident = Binder.clearCallingIdentity();
9533        try {
9534            removeContentProviderExternalUnchecked(name, token, userId);
9535        } finally {
9536            Binder.restoreCallingIdentity(ident);
9537        }
9538    }
9539
9540    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9541        synchronized (this) {
9542            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9543            if(cpr == null) {
9544                //remove from mProvidersByClass
9545                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9546                return;
9547            }
9548
9549            //update content provider record entry info
9550            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9551            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9552            if (localCpr.hasExternalProcessHandles()) {
9553                if (localCpr.removeExternalProcessHandleLocked(token)) {
9554                    updateOomAdjLocked();
9555                } else {
9556                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9557                            + " with no external reference for token: "
9558                            + token + ".");
9559                }
9560            } else {
9561                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9562                        + " with no external references.");
9563            }
9564        }
9565    }
9566
9567    public final void publishContentProviders(IApplicationThread caller,
9568            List<ContentProviderHolder> providers) {
9569        if (providers == null) {
9570            return;
9571        }
9572
9573        enforceNotIsolatedCaller("publishContentProviders");
9574        synchronized (this) {
9575            final ProcessRecord r = getRecordForAppLocked(caller);
9576            if (DEBUG_MU)
9577                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9578            if (r == null) {
9579                throw new SecurityException(
9580                        "Unable to find app for caller " + caller
9581                      + " (pid=" + Binder.getCallingPid()
9582                      + ") when publishing content providers");
9583            }
9584
9585            final long origId = Binder.clearCallingIdentity();
9586
9587            final int N = providers.size();
9588            for (int i=0; i<N; i++) {
9589                ContentProviderHolder src = providers.get(i);
9590                if (src == null || src.info == null || src.provider == null) {
9591                    continue;
9592                }
9593                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9594                if (DEBUG_MU)
9595                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9596                if (dst != null) {
9597                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9598                    mProviderMap.putProviderByClass(comp, dst);
9599                    String names[] = dst.info.authority.split(";");
9600                    for (int j = 0; j < names.length; j++) {
9601                        mProviderMap.putProviderByName(names[j], dst);
9602                    }
9603
9604                    int NL = mLaunchingProviders.size();
9605                    int j;
9606                    for (j=0; j<NL; j++) {
9607                        if (mLaunchingProviders.get(j) == dst) {
9608                            mLaunchingProviders.remove(j);
9609                            j--;
9610                            NL--;
9611                        }
9612                    }
9613                    synchronized (dst) {
9614                        dst.provider = src.provider;
9615                        dst.proc = r;
9616                        dst.notifyAll();
9617                    }
9618                    updateOomAdjLocked(r);
9619                }
9620            }
9621
9622            Binder.restoreCallingIdentity(origId);
9623        }
9624    }
9625
9626    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9627        ContentProviderConnection conn;
9628        try {
9629            conn = (ContentProviderConnection)connection;
9630        } catch (ClassCastException e) {
9631            String msg ="refContentProvider: " + connection
9632                    + " not a ContentProviderConnection";
9633            Slog.w(TAG, msg);
9634            throw new IllegalArgumentException(msg);
9635        }
9636        if (conn == null) {
9637            throw new NullPointerException("connection is null");
9638        }
9639
9640        synchronized (this) {
9641            if (stable > 0) {
9642                conn.numStableIncs += stable;
9643            }
9644            stable = conn.stableCount + stable;
9645            if (stable < 0) {
9646                throw new IllegalStateException("stableCount < 0: " + stable);
9647            }
9648
9649            if (unstable > 0) {
9650                conn.numUnstableIncs += unstable;
9651            }
9652            unstable = conn.unstableCount + unstable;
9653            if (unstable < 0) {
9654                throw new IllegalStateException("unstableCount < 0: " + unstable);
9655            }
9656
9657            if ((stable+unstable) <= 0) {
9658                throw new IllegalStateException("ref counts can't go to zero here: stable="
9659                        + stable + " unstable=" + unstable);
9660            }
9661            conn.stableCount = stable;
9662            conn.unstableCount = unstable;
9663            return !conn.dead;
9664        }
9665    }
9666
9667    public void unstableProviderDied(IBinder connection) {
9668        ContentProviderConnection conn;
9669        try {
9670            conn = (ContentProviderConnection)connection;
9671        } catch (ClassCastException e) {
9672            String msg ="refContentProvider: " + connection
9673                    + " not a ContentProviderConnection";
9674            Slog.w(TAG, msg);
9675            throw new IllegalArgumentException(msg);
9676        }
9677        if (conn == null) {
9678            throw new NullPointerException("connection is null");
9679        }
9680
9681        // Safely retrieve the content provider associated with the connection.
9682        IContentProvider provider;
9683        synchronized (this) {
9684            provider = conn.provider.provider;
9685        }
9686
9687        if (provider == null) {
9688            // Um, yeah, we're way ahead of you.
9689            return;
9690        }
9691
9692        // Make sure the caller is being honest with us.
9693        if (provider.asBinder().pingBinder()) {
9694            // Er, no, still looks good to us.
9695            synchronized (this) {
9696                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9697                        + " says " + conn + " died, but we don't agree");
9698                return;
9699            }
9700        }
9701
9702        // Well look at that!  It's dead!
9703        synchronized (this) {
9704            if (conn.provider.provider != provider) {
9705                // But something changed...  good enough.
9706                return;
9707            }
9708
9709            ProcessRecord proc = conn.provider.proc;
9710            if (proc == null || proc.thread == null) {
9711                // Seems like the process is already cleaned up.
9712                return;
9713            }
9714
9715            // As far as we're concerned, this is just like receiving a
9716            // death notification...  just a bit prematurely.
9717            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9718                    + ") early provider death");
9719            final long ident = Binder.clearCallingIdentity();
9720            try {
9721                appDiedLocked(proc);
9722            } finally {
9723                Binder.restoreCallingIdentity(ident);
9724            }
9725        }
9726    }
9727
9728    @Override
9729    public void appNotRespondingViaProvider(IBinder connection) {
9730        enforceCallingPermission(
9731                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9732
9733        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9734        if (conn == null) {
9735            Slog.w(TAG, "ContentProviderConnection is null");
9736            return;
9737        }
9738
9739        final ProcessRecord host = conn.provider.proc;
9740        if (host == null) {
9741            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9742            return;
9743        }
9744
9745        final long token = Binder.clearCallingIdentity();
9746        try {
9747            appNotResponding(host, null, null, false, "ContentProvider not responding");
9748        } finally {
9749            Binder.restoreCallingIdentity(token);
9750        }
9751    }
9752
9753    public final void installSystemProviders() {
9754        List<ProviderInfo> providers;
9755        synchronized (this) {
9756            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9757            providers = generateApplicationProvidersLocked(app);
9758            if (providers != null) {
9759                for (int i=providers.size()-1; i>=0; i--) {
9760                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9761                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9762                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9763                                + ": not system .apk");
9764                        providers.remove(i);
9765                    }
9766                }
9767            }
9768        }
9769        if (providers != null) {
9770            mSystemThread.installSystemProviders(providers);
9771        }
9772
9773        mCoreSettingsObserver = new CoreSettingsObserver(this);
9774
9775        //mUsageStatsService.monitorPackages();
9776    }
9777
9778    /**
9779     * Allows apps to retrieve the MIME type of a URI.
9780     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9781     * users, then it does not need permission to access the ContentProvider.
9782     * Either, it needs cross-user uri grants.
9783     *
9784     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9785     *
9786     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9787     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9788     */
9789    public String getProviderMimeType(Uri uri, int userId) {
9790        enforceNotIsolatedCaller("getProviderMimeType");
9791        final String name = uri.getAuthority();
9792        int callingUid = Binder.getCallingUid();
9793        int callingPid = Binder.getCallingPid();
9794        long ident = 0;
9795        boolean clearedIdentity = false;
9796        userId = unsafeConvertIncomingUser(userId);
9797        if (canClearIdentity(callingPid, callingUid, userId)) {
9798            clearedIdentity = true;
9799            ident = Binder.clearCallingIdentity();
9800        }
9801        ContentProviderHolder holder = null;
9802        try {
9803            holder = getContentProviderExternalUnchecked(name, null, userId);
9804            if (holder != null) {
9805                return holder.provider.getType(uri);
9806            }
9807        } catch (RemoteException e) {
9808            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9809            return null;
9810        } finally {
9811            // We need to clear the identity to call removeContentProviderExternalUnchecked
9812            if (!clearedIdentity) {
9813                ident = Binder.clearCallingIdentity();
9814            }
9815            try {
9816                if (holder != null) {
9817                    removeContentProviderExternalUnchecked(name, null, userId);
9818                }
9819            } finally {
9820                Binder.restoreCallingIdentity(ident);
9821            }
9822        }
9823
9824        return null;
9825    }
9826
9827    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9828        if (UserHandle.getUserId(callingUid) == userId) {
9829            return true;
9830        }
9831        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9832                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9833                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9834                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9835                return true;
9836        }
9837        return false;
9838    }
9839
9840    // =========================================================
9841    // GLOBAL MANAGEMENT
9842    // =========================================================
9843
9844    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9845            boolean isolated, int isolatedUid) {
9846        String proc = customProcess != null ? customProcess : info.processName;
9847        BatteryStatsImpl.Uid.Proc ps = null;
9848        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9849        int uid = info.uid;
9850        if (isolated) {
9851            if (isolatedUid == 0) {
9852                int userId = UserHandle.getUserId(uid);
9853                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9854                while (true) {
9855                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9856                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9857                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9858                    }
9859                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9860                    mNextIsolatedProcessUid++;
9861                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9862                        // No process for this uid, use it.
9863                        break;
9864                    }
9865                    stepsLeft--;
9866                    if (stepsLeft <= 0) {
9867                        return null;
9868                    }
9869                }
9870            } else {
9871                // Special case for startIsolatedProcess (internal only), where
9872                // the uid of the isolated process is specified by the caller.
9873                uid = isolatedUid;
9874            }
9875        }
9876        return new ProcessRecord(stats, info, proc, uid);
9877    }
9878
9879    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9880            String abiOverride) {
9881        ProcessRecord app;
9882        if (!isolated) {
9883            app = getProcessRecordLocked(info.processName, info.uid, true);
9884        } else {
9885            app = null;
9886        }
9887
9888        if (app == null) {
9889            app = newProcessRecordLocked(info, null, isolated, 0);
9890            mProcessNames.put(info.processName, app.uid, app);
9891            if (isolated) {
9892                mIsolatedProcesses.put(app.uid, app);
9893            }
9894            updateLruProcessLocked(app, false, null);
9895            updateOomAdjLocked();
9896        }
9897
9898        // This package really, really can not be stopped.
9899        try {
9900            AppGlobals.getPackageManager().setPackageStoppedState(
9901                    info.packageName, false, UserHandle.getUserId(app.uid));
9902        } catch (RemoteException e) {
9903        } catch (IllegalArgumentException e) {
9904            Slog.w(TAG, "Failed trying to unstop package "
9905                    + info.packageName + ": " + e);
9906        }
9907
9908        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9909                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9910            app.persistent = true;
9911            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9912        }
9913        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9914            mPersistentStartingProcesses.add(app);
9915            startProcessLocked(app, "added application", app.processName, abiOverride,
9916                    null /* entryPoint */, null /* entryPointArgs */);
9917        }
9918
9919        return app;
9920    }
9921
9922    public void unhandledBack() {
9923        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9924                "unhandledBack()");
9925
9926        synchronized(this) {
9927            final long origId = Binder.clearCallingIdentity();
9928            try {
9929                getFocusedStack().unhandledBackLocked();
9930            } finally {
9931                Binder.restoreCallingIdentity(origId);
9932            }
9933        }
9934    }
9935
9936    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9937        enforceNotIsolatedCaller("openContentUri");
9938        final int userId = UserHandle.getCallingUserId();
9939        String name = uri.getAuthority();
9940        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9941        ParcelFileDescriptor pfd = null;
9942        if (cph != null) {
9943            // We record the binder invoker's uid in thread-local storage before
9944            // going to the content provider to open the file.  Later, in the code
9945            // that handles all permissions checks, we look for this uid and use
9946            // that rather than the Activity Manager's own uid.  The effect is that
9947            // we do the check against the caller's permissions even though it looks
9948            // to the content provider like the Activity Manager itself is making
9949            // the request.
9950            Binder token = new Binder();
9951            sCallerIdentity.set(new Identity(
9952                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9953            try {
9954                pfd = cph.provider.openFile(null, uri, "r", null, token);
9955            } catch (FileNotFoundException e) {
9956                // do nothing; pfd will be returned null
9957            } finally {
9958                // Ensure that whatever happens, we clean up the identity state
9959                sCallerIdentity.remove();
9960            }
9961
9962            // We've got the fd now, so we're done with the provider.
9963            removeContentProviderExternalUnchecked(name, null, userId);
9964        } else {
9965            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9966        }
9967        return pfd;
9968    }
9969
9970    // Actually is sleeping or shutting down or whatever else in the future
9971    // is an inactive state.
9972    public boolean isSleepingOrShuttingDown() {
9973        return isSleeping() || mShuttingDown;
9974    }
9975
9976    public boolean isSleeping() {
9977        return mSleeping;
9978    }
9979
9980    void onWakefulnessChanged(int wakefulness) {
9981        synchronized(this) {
9982            mWakefulness = wakefulness;
9983            updateSleepIfNeededLocked();
9984        }
9985    }
9986
9987    void finishRunningVoiceLocked() {
9988        if (mRunningVoice) {
9989            mRunningVoice = false;
9990            updateSleepIfNeededLocked();
9991        }
9992    }
9993
9994    void updateSleepIfNeededLocked() {
9995        if (mSleeping && !shouldSleepLocked()) {
9996            mSleeping = false;
9997            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9998        } else if (!mSleeping && shouldSleepLocked()) {
9999            mSleeping = true;
10000            mStackSupervisor.goingToSleepLocked();
10001
10002            // Initialize the wake times of all processes.
10003            checkExcessivePowerUsageLocked(false);
10004            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10005            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10006            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10007        }
10008    }
10009
10010    private boolean shouldSleepLocked() {
10011        // Resume applications while running a voice interactor.
10012        if (mRunningVoice) {
10013            return false;
10014        }
10015
10016        switch (mWakefulness) {
10017            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10018            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10019                // If we're interactive but applications are already paused then defer
10020                // resuming them until the lock screen is hidden.
10021                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10022            case PowerManagerInternal.WAKEFULNESS_DOZING:
10023                // If we're dozing then pause applications whenever the lock screen is shown.
10024                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10025            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10026            default:
10027                // If we're asleep then pause applications unconditionally.
10028                return true;
10029        }
10030    }
10031
10032    /** Pokes the task persister. */
10033    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10034        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10035            // Never persist the home stack.
10036            return;
10037        }
10038        mTaskPersister.wakeup(task, flush);
10039    }
10040
10041    /** Notifies all listeners when the task stack has changed. */
10042    void notifyTaskStackChangedLocked() {
10043        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10044        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10045        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10046    }
10047
10048    @Override
10049    public boolean shutdown(int timeout) {
10050        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10051                != PackageManager.PERMISSION_GRANTED) {
10052            throw new SecurityException("Requires permission "
10053                    + android.Manifest.permission.SHUTDOWN);
10054        }
10055
10056        boolean timedout = false;
10057
10058        synchronized(this) {
10059            mShuttingDown = true;
10060            updateEventDispatchingLocked();
10061            timedout = mStackSupervisor.shutdownLocked(timeout);
10062        }
10063
10064        mAppOpsService.shutdown();
10065        if (mUsageStatsService != null) {
10066            mUsageStatsService.prepareShutdown();
10067        }
10068        mBatteryStatsService.shutdown();
10069        synchronized (this) {
10070            mProcessStats.shutdownLocked();
10071            notifyTaskPersisterLocked(null, true);
10072        }
10073
10074        return timedout;
10075    }
10076
10077    public final void activitySlept(IBinder token) {
10078        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10079
10080        final long origId = Binder.clearCallingIdentity();
10081
10082        synchronized (this) {
10083            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10084            if (r != null) {
10085                mStackSupervisor.activitySleptLocked(r);
10086            }
10087        }
10088
10089        Binder.restoreCallingIdentity(origId);
10090    }
10091
10092    private String lockScreenShownToString() {
10093        switch (mLockScreenShown) {
10094            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10095            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10096            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10097            default: return "Unknown=" + mLockScreenShown;
10098        }
10099    }
10100
10101    void logLockScreen(String msg) {
10102        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10103                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10104                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10105                + " mSleeping=" + mSleeping);
10106    }
10107
10108    void startRunningVoiceLocked() {
10109        if (!mRunningVoice) {
10110            mRunningVoice = true;
10111            updateSleepIfNeededLocked();
10112        }
10113    }
10114
10115    private void updateEventDispatchingLocked() {
10116        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10117    }
10118
10119    public void setLockScreenShown(boolean shown) {
10120        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10121                != PackageManager.PERMISSION_GRANTED) {
10122            throw new SecurityException("Requires permission "
10123                    + android.Manifest.permission.DEVICE_POWER);
10124        }
10125
10126        synchronized(this) {
10127            long ident = Binder.clearCallingIdentity();
10128            try {
10129                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10130                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10131                updateSleepIfNeededLocked();
10132            } finally {
10133                Binder.restoreCallingIdentity(ident);
10134            }
10135        }
10136    }
10137
10138    @Override
10139    public void stopAppSwitches() {
10140        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10141                != PackageManager.PERMISSION_GRANTED) {
10142            throw new SecurityException("Requires permission "
10143                    + android.Manifest.permission.STOP_APP_SWITCHES);
10144        }
10145
10146        synchronized(this) {
10147            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10148                    + APP_SWITCH_DELAY_TIME;
10149            mDidAppSwitch = false;
10150            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10151            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10152            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10153        }
10154    }
10155
10156    public void resumeAppSwitches() {
10157        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10158                != PackageManager.PERMISSION_GRANTED) {
10159            throw new SecurityException("Requires permission "
10160                    + android.Manifest.permission.STOP_APP_SWITCHES);
10161        }
10162
10163        synchronized(this) {
10164            // Note that we don't execute any pending app switches... we will
10165            // let those wait until either the timeout, or the next start
10166            // activity request.
10167            mAppSwitchesAllowedTime = 0;
10168        }
10169    }
10170
10171    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10172            int callingPid, int callingUid, String name) {
10173        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10174            return true;
10175        }
10176
10177        int perm = checkComponentPermission(
10178                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10179                sourceUid, -1, true);
10180        if (perm == PackageManager.PERMISSION_GRANTED) {
10181            return true;
10182        }
10183
10184        // If the actual IPC caller is different from the logical source, then
10185        // also see if they are allowed to control app switches.
10186        if (callingUid != -1 && callingUid != sourceUid) {
10187            perm = checkComponentPermission(
10188                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10189                    callingUid, -1, true);
10190            if (perm == PackageManager.PERMISSION_GRANTED) {
10191                return true;
10192            }
10193        }
10194
10195        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10196        return false;
10197    }
10198
10199    public void setDebugApp(String packageName, boolean waitForDebugger,
10200            boolean persistent) {
10201        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10202                "setDebugApp()");
10203
10204        long ident = Binder.clearCallingIdentity();
10205        try {
10206            // Note that this is not really thread safe if there are multiple
10207            // callers into it at the same time, but that's not a situation we
10208            // care about.
10209            if (persistent) {
10210                final ContentResolver resolver = mContext.getContentResolver();
10211                Settings.Global.putString(
10212                    resolver, Settings.Global.DEBUG_APP,
10213                    packageName);
10214                Settings.Global.putInt(
10215                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10216                    waitForDebugger ? 1 : 0);
10217            }
10218
10219            synchronized (this) {
10220                if (!persistent) {
10221                    mOrigDebugApp = mDebugApp;
10222                    mOrigWaitForDebugger = mWaitForDebugger;
10223                }
10224                mDebugApp = packageName;
10225                mWaitForDebugger = waitForDebugger;
10226                mDebugTransient = !persistent;
10227                if (packageName != null) {
10228                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10229                            false, UserHandle.USER_ALL, "set debug app");
10230                }
10231            }
10232        } finally {
10233            Binder.restoreCallingIdentity(ident);
10234        }
10235    }
10236
10237    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10238        synchronized (this) {
10239            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10240            if (!isDebuggable) {
10241                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10242                    throw new SecurityException("Process not debuggable: " + app.packageName);
10243                }
10244            }
10245
10246            mOpenGlTraceApp = processName;
10247        }
10248    }
10249
10250    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10251        synchronized (this) {
10252            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10253            if (!isDebuggable) {
10254                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10255                    throw new SecurityException("Process not debuggable: " + app.packageName);
10256                }
10257            }
10258            mProfileApp = processName;
10259            mProfileFile = profilerInfo.profileFile;
10260            if (mProfileFd != null) {
10261                try {
10262                    mProfileFd.close();
10263                } catch (IOException e) {
10264                }
10265                mProfileFd = null;
10266            }
10267            mProfileFd = profilerInfo.profileFd;
10268            mSamplingInterval = profilerInfo.samplingInterval;
10269            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10270            mProfileType = 0;
10271        }
10272    }
10273
10274    @Override
10275    public void setAlwaysFinish(boolean enabled) {
10276        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10277                "setAlwaysFinish()");
10278
10279        Settings.Global.putInt(
10280                mContext.getContentResolver(),
10281                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10282
10283        synchronized (this) {
10284            mAlwaysFinishActivities = enabled;
10285        }
10286    }
10287
10288    @Override
10289    public void setActivityController(IActivityController controller) {
10290        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10291                "setActivityController()");
10292        synchronized (this) {
10293            mController = controller;
10294            Watchdog.getInstance().setActivityController(controller);
10295        }
10296    }
10297
10298    @Override
10299    public void setUserIsMonkey(boolean userIsMonkey) {
10300        synchronized (this) {
10301            synchronized (mPidsSelfLocked) {
10302                final int callingPid = Binder.getCallingPid();
10303                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10304                if (precessRecord == null) {
10305                    throw new SecurityException("Unknown process: " + callingPid);
10306                }
10307                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10308                    throw new SecurityException("Only an instrumentation process "
10309                            + "with a UiAutomation can call setUserIsMonkey");
10310                }
10311            }
10312            mUserIsMonkey = userIsMonkey;
10313        }
10314    }
10315
10316    @Override
10317    public boolean isUserAMonkey() {
10318        synchronized (this) {
10319            // If there is a controller also implies the user is a monkey.
10320            return (mUserIsMonkey || mController != null);
10321        }
10322    }
10323
10324    public void requestBugReport() {
10325        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10326        SystemProperties.set("ctl.start", "bugreport");
10327    }
10328
10329    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10330        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10331    }
10332
10333    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10334        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10335            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10336        }
10337        return KEY_DISPATCHING_TIMEOUT;
10338    }
10339
10340    @Override
10341    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10342        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10343                != PackageManager.PERMISSION_GRANTED) {
10344            throw new SecurityException("Requires permission "
10345                    + android.Manifest.permission.FILTER_EVENTS);
10346        }
10347        ProcessRecord proc;
10348        long timeout;
10349        synchronized (this) {
10350            synchronized (mPidsSelfLocked) {
10351                proc = mPidsSelfLocked.get(pid);
10352            }
10353            timeout = getInputDispatchingTimeoutLocked(proc);
10354        }
10355
10356        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10357            return -1;
10358        }
10359
10360        return timeout;
10361    }
10362
10363    /**
10364     * Handle input dispatching timeouts.
10365     * Returns whether input dispatching should be aborted or not.
10366     */
10367    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10368            final ActivityRecord activity, final ActivityRecord parent,
10369            final boolean aboveSystem, String reason) {
10370        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10371                != PackageManager.PERMISSION_GRANTED) {
10372            throw new SecurityException("Requires permission "
10373                    + android.Manifest.permission.FILTER_EVENTS);
10374        }
10375
10376        final String annotation;
10377        if (reason == null) {
10378            annotation = "Input dispatching timed out";
10379        } else {
10380            annotation = "Input dispatching timed out (" + reason + ")";
10381        }
10382
10383        if (proc != null) {
10384            synchronized (this) {
10385                if (proc.debugging) {
10386                    return false;
10387                }
10388
10389                if (mDidDexOpt) {
10390                    // Give more time since we were dexopting.
10391                    mDidDexOpt = false;
10392                    return false;
10393                }
10394
10395                if (proc.instrumentationClass != null) {
10396                    Bundle info = new Bundle();
10397                    info.putString("shortMsg", "keyDispatchingTimedOut");
10398                    info.putString("longMsg", annotation);
10399                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10400                    return true;
10401                }
10402            }
10403            mHandler.post(new Runnable() {
10404                @Override
10405                public void run() {
10406                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10407                }
10408            });
10409        }
10410
10411        return true;
10412    }
10413
10414    public Bundle getAssistContextExtras(int requestType) {
10415        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10416                UserHandle.getCallingUserId());
10417        if (pae == null) {
10418            return null;
10419        }
10420        synchronized (pae) {
10421            while (!pae.haveResult) {
10422                try {
10423                    pae.wait();
10424                } catch (InterruptedException e) {
10425                }
10426            }
10427            if (pae.result != null) {
10428                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10429            }
10430        }
10431        synchronized (this) {
10432            mPendingAssistExtras.remove(pae);
10433            mHandler.removeCallbacks(pae);
10434        }
10435        return pae.extras;
10436    }
10437
10438    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10439            int userHandle) {
10440        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10441                "getAssistContextExtras()");
10442        PendingAssistExtras pae;
10443        Bundle extras = new Bundle();
10444        synchronized (this) {
10445            ActivityRecord activity = getFocusedStack().mResumedActivity;
10446            if (activity == null) {
10447                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10448                return null;
10449            }
10450            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10451            if (activity.app == null || activity.app.thread == null) {
10452                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10453                return null;
10454            }
10455            if (activity.app.pid == Binder.getCallingPid()) {
10456                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10457                return null;
10458            }
10459            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10460            try {
10461                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10462                        requestType);
10463                mPendingAssistExtras.add(pae);
10464                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10465            } catch (RemoteException e) {
10466                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10467                return null;
10468            }
10469            return pae;
10470        }
10471    }
10472
10473    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10474        PendingAssistExtras pae = (PendingAssistExtras)token;
10475        synchronized (pae) {
10476            pae.result = extras;
10477            pae.haveResult = true;
10478            pae.notifyAll();
10479            if (pae.intent == null) {
10480                // Caller is just waiting for the result.
10481                return;
10482            }
10483        }
10484
10485        // We are now ready to launch the assist activity.
10486        synchronized (this) {
10487            boolean exists = mPendingAssistExtras.remove(pae);
10488            mHandler.removeCallbacks(pae);
10489            if (!exists) {
10490                // Timed out.
10491                return;
10492            }
10493        }
10494        pae.intent.replaceExtras(extras);
10495        if (pae.hint != null) {
10496            pae.intent.putExtra(pae.hint, true);
10497        }
10498        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10499                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10500                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10501        closeSystemDialogs("assist");
10502        try {
10503            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10504        } catch (ActivityNotFoundException e) {
10505            Slog.w(TAG, "No activity to handle assist action.", e);
10506        }
10507    }
10508
10509    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10510        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10511    }
10512
10513    public void registerProcessObserver(IProcessObserver observer) {
10514        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10515                "registerProcessObserver()");
10516        synchronized (this) {
10517            mProcessObservers.register(observer);
10518        }
10519    }
10520
10521    @Override
10522    public void unregisterProcessObserver(IProcessObserver observer) {
10523        synchronized (this) {
10524            mProcessObservers.unregister(observer);
10525        }
10526    }
10527
10528    @Override
10529    public boolean convertFromTranslucent(IBinder token) {
10530        final long origId = Binder.clearCallingIdentity();
10531        try {
10532            synchronized (this) {
10533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10534                if (r == null) {
10535                    return false;
10536                }
10537                final boolean translucentChanged = r.changeWindowTranslucency(true);
10538                if (translucentChanged) {
10539                    r.task.stack.releaseBackgroundResources();
10540                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10541                }
10542                mWindowManager.setAppFullscreen(token, true);
10543                return translucentChanged;
10544            }
10545        } finally {
10546            Binder.restoreCallingIdentity(origId);
10547        }
10548    }
10549
10550    @Override
10551    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10552        final long origId = Binder.clearCallingIdentity();
10553        try {
10554            synchronized (this) {
10555                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10556                if (r == null) {
10557                    return false;
10558                }
10559                int index = r.task.mActivities.lastIndexOf(r);
10560                if (index > 0) {
10561                    ActivityRecord under = r.task.mActivities.get(index - 1);
10562                    under.returningOptions = options;
10563                }
10564                final boolean translucentChanged = r.changeWindowTranslucency(false);
10565                if (translucentChanged) {
10566                    r.task.stack.convertToTranslucent(r);
10567                }
10568                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10569                mWindowManager.setAppFullscreen(token, false);
10570                return translucentChanged;
10571            }
10572        } finally {
10573            Binder.restoreCallingIdentity(origId);
10574        }
10575    }
10576
10577    @Override
10578    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10579        final long origId = Binder.clearCallingIdentity();
10580        try {
10581            synchronized (this) {
10582                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10583                if (r != null) {
10584                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10585                }
10586            }
10587            return false;
10588        } finally {
10589            Binder.restoreCallingIdentity(origId);
10590        }
10591    }
10592
10593    @Override
10594    public boolean isBackgroundVisibleBehind(IBinder token) {
10595        final long origId = Binder.clearCallingIdentity();
10596        try {
10597            synchronized (this) {
10598                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10599                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10600                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10601                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10602                return visible;
10603            }
10604        } finally {
10605            Binder.restoreCallingIdentity(origId);
10606        }
10607    }
10608
10609    @Override
10610    public ActivityOptions getActivityOptions(IBinder token) {
10611        final long origId = Binder.clearCallingIdentity();
10612        try {
10613            synchronized (this) {
10614                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10615                if (r != null) {
10616                    final ActivityOptions activityOptions = r.pendingOptions;
10617                    r.pendingOptions = null;
10618                    return activityOptions;
10619                }
10620                return null;
10621            }
10622        } finally {
10623            Binder.restoreCallingIdentity(origId);
10624        }
10625    }
10626
10627    @Override
10628    public void setImmersive(IBinder token, boolean immersive) {
10629        synchronized(this) {
10630            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10631            if (r == null) {
10632                throw new IllegalArgumentException();
10633            }
10634            r.immersive = immersive;
10635
10636            // update associated state if we're frontmost
10637            if (r == mFocusedActivity) {
10638                if (DEBUG_IMMERSIVE) {
10639                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10640                }
10641                applyUpdateLockStateLocked(r);
10642            }
10643        }
10644    }
10645
10646    @Override
10647    public boolean isImmersive(IBinder token) {
10648        synchronized (this) {
10649            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10650            if (r == null) {
10651                throw new IllegalArgumentException();
10652            }
10653            return r.immersive;
10654        }
10655    }
10656
10657    public boolean isTopActivityImmersive() {
10658        enforceNotIsolatedCaller("startActivity");
10659        synchronized (this) {
10660            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10661            return (r != null) ? r.immersive : false;
10662        }
10663    }
10664
10665    @Override
10666    public boolean isTopOfTask(IBinder token) {
10667        synchronized (this) {
10668            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10669            if (r == null) {
10670                throw new IllegalArgumentException();
10671            }
10672            return r.task.getTopActivity() == r;
10673        }
10674    }
10675
10676    public final void enterSafeMode() {
10677        synchronized(this) {
10678            // It only makes sense to do this before the system is ready
10679            // and started launching other packages.
10680            if (!mSystemReady) {
10681                try {
10682                    AppGlobals.getPackageManager().enterSafeMode();
10683                } catch (RemoteException e) {
10684                }
10685            }
10686
10687            mSafeMode = true;
10688        }
10689    }
10690
10691    public final void showSafeModeOverlay() {
10692        View v = LayoutInflater.from(mContext).inflate(
10693                com.android.internal.R.layout.safe_mode, null);
10694        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10695        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10696        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10697        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10698        lp.gravity = Gravity.BOTTOM | Gravity.START;
10699        lp.format = v.getBackground().getOpacity();
10700        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10701                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10702        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10703        ((WindowManager)mContext.getSystemService(
10704                Context.WINDOW_SERVICE)).addView(v, lp);
10705    }
10706
10707    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10708        if (!(sender instanceof PendingIntentRecord)) {
10709            return;
10710        }
10711        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10712        synchronized (stats) {
10713            if (mBatteryStatsService.isOnBattery()) {
10714                mBatteryStatsService.enforceCallingPermission();
10715                PendingIntentRecord rec = (PendingIntentRecord)sender;
10716                int MY_UID = Binder.getCallingUid();
10717                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10718                BatteryStatsImpl.Uid.Pkg pkg =
10719                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10720                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10721                pkg.incWakeupsLocked();
10722            }
10723        }
10724    }
10725
10726    public boolean killPids(int[] pids, String pReason, boolean secure) {
10727        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10728            throw new SecurityException("killPids only available to the system");
10729        }
10730        String reason = (pReason == null) ? "Unknown" : pReason;
10731        // XXX Note: don't acquire main activity lock here, because the window
10732        // manager calls in with its locks held.
10733
10734        boolean killed = false;
10735        synchronized (mPidsSelfLocked) {
10736            int[] types = new int[pids.length];
10737            int worstType = 0;
10738            for (int i=0; i<pids.length; i++) {
10739                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10740                if (proc != null) {
10741                    int type = proc.setAdj;
10742                    types[i] = type;
10743                    if (type > worstType) {
10744                        worstType = type;
10745                    }
10746                }
10747            }
10748
10749            // If the worst oom_adj is somewhere in the cached proc LRU range,
10750            // then constrain it so we will kill all cached procs.
10751            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10752                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10753                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10754            }
10755
10756            // If this is not a secure call, don't let it kill processes that
10757            // are important.
10758            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10759                worstType = ProcessList.SERVICE_ADJ;
10760            }
10761
10762            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10763            for (int i=0; i<pids.length; i++) {
10764                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10765                if (proc == null) {
10766                    continue;
10767                }
10768                int adj = proc.setAdj;
10769                if (adj >= worstType && !proc.killedByAm) {
10770                    proc.kill(reason, true);
10771                    killed = true;
10772                }
10773            }
10774        }
10775        return killed;
10776    }
10777
10778    @Override
10779    public void killUid(int uid, String reason) {
10780        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10781            throw new SecurityException("killUid only available to the system");
10782        }
10783        synchronized (this) {
10784            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10785                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10786                    reason != null ? reason : "kill uid");
10787        }
10788    }
10789
10790    @Override
10791    public boolean killProcessesBelowForeground(String reason) {
10792        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10793            throw new SecurityException("killProcessesBelowForeground() only available to system");
10794        }
10795
10796        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10797    }
10798
10799    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10800        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10801            throw new SecurityException("killProcessesBelowAdj() only available to system");
10802        }
10803
10804        boolean killed = false;
10805        synchronized (mPidsSelfLocked) {
10806            final int size = mPidsSelfLocked.size();
10807            for (int i = 0; i < size; i++) {
10808                final int pid = mPidsSelfLocked.keyAt(i);
10809                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10810                if (proc == null) continue;
10811
10812                final int adj = proc.setAdj;
10813                if (adj > belowAdj && !proc.killedByAm) {
10814                    proc.kill(reason, true);
10815                    killed = true;
10816                }
10817            }
10818        }
10819        return killed;
10820    }
10821
10822    @Override
10823    public void hang(final IBinder who, boolean allowRestart) {
10824        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10825                != PackageManager.PERMISSION_GRANTED) {
10826            throw new SecurityException("Requires permission "
10827                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10828        }
10829
10830        final IBinder.DeathRecipient death = new DeathRecipient() {
10831            @Override
10832            public void binderDied() {
10833                synchronized (this) {
10834                    notifyAll();
10835                }
10836            }
10837        };
10838
10839        try {
10840            who.linkToDeath(death, 0);
10841        } catch (RemoteException e) {
10842            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10843            return;
10844        }
10845
10846        synchronized (this) {
10847            Watchdog.getInstance().setAllowRestart(allowRestart);
10848            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10849            synchronized (death) {
10850                while (who.isBinderAlive()) {
10851                    try {
10852                        death.wait();
10853                    } catch (InterruptedException e) {
10854                    }
10855                }
10856            }
10857            Watchdog.getInstance().setAllowRestart(true);
10858        }
10859    }
10860
10861    @Override
10862    public void restart() {
10863        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10864                != PackageManager.PERMISSION_GRANTED) {
10865            throw new SecurityException("Requires permission "
10866                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10867        }
10868
10869        Log.i(TAG, "Sending shutdown broadcast...");
10870
10871        BroadcastReceiver br = new BroadcastReceiver() {
10872            @Override public void onReceive(Context context, Intent intent) {
10873                // Now the broadcast is done, finish up the low-level shutdown.
10874                Log.i(TAG, "Shutting down activity manager...");
10875                shutdown(10000);
10876                Log.i(TAG, "Shutdown complete, restarting!");
10877                Process.killProcess(Process.myPid());
10878                System.exit(10);
10879            }
10880        };
10881
10882        // First send the high-level shut down broadcast.
10883        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10884        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10885        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10886        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10887        mContext.sendOrderedBroadcastAsUser(intent,
10888                UserHandle.ALL, null, br, mHandler, 0, null, null);
10889        */
10890        br.onReceive(mContext, intent);
10891    }
10892
10893    private long getLowRamTimeSinceIdle(long now) {
10894        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10895    }
10896
10897    @Override
10898    public void performIdleMaintenance() {
10899        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10900                != PackageManager.PERMISSION_GRANTED) {
10901            throw new SecurityException("Requires permission "
10902                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10903        }
10904
10905        synchronized (this) {
10906            final long now = SystemClock.uptimeMillis();
10907            final long timeSinceLastIdle = now - mLastIdleTime;
10908            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10909            mLastIdleTime = now;
10910            mLowRamTimeSinceLastIdle = 0;
10911            if (mLowRamStartTime != 0) {
10912                mLowRamStartTime = now;
10913            }
10914
10915            StringBuilder sb = new StringBuilder(128);
10916            sb.append("Idle maintenance over ");
10917            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10918            sb.append(" low RAM for ");
10919            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10920            Slog.i(TAG, sb.toString());
10921
10922            // If at least 1/3 of our time since the last idle period has been spent
10923            // with RAM low, then we want to kill processes.
10924            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10925
10926            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10927                ProcessRecord proc = mLruProcesses.get(i);
10928                if (proc.notCachedSinceIdle) {
10929                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10930                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10931                        if (doKilling && proc.initialIdlePss != 0
10932                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10933                            sb = new StringBuilder(128);
10934                            sb.append("Kill");
10935                            sb.append(proc.processName);
10936                            sb.append(" in idle maint: pss=");
10937                            sb.append(proc.lastPss);
10938                            sb.append(", initialPss=");
10939                            sb.append(proc.initialIdlePss);
10940                            sb.append(", period=");
10941                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10942                            sb.append(", lowRamPeriod=");
10943                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10944                            Slog.wtfQuiet(TAG, sb.toString());
10945                            proc.kill("idle maint (pss " + proc.lastPss
10946                                    + " from " + proc.initialIdlePss + ")", true);
10947                        }
10948                    }
10949                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10950                    proc.notCachedSinceIdle = true;
10951                    proc.initialIdlePss = 0;
10952                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10953                            mTestPssMode, isSleeping(), now);
10954                }
10955            }
10956
10957            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10958            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10959        }
10960    }
10961
10962    private void retrieveSettings() {
10963        final ContentResolver resolver = mContext.getContentResolver();
10964        String debugApp = Settings.Global.getString(
10965            resolver, Settings.Global.DEBUG_APP);
10966        boolean waitForDebugger = Settings.Global.getInt(
10967            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10968        boolean alwaysFinishActivities = Settings.Global.getInt(
10969            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10970        boolean forceRtl = Settings.Global.getInt(
10971                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10972        // Transfer any global setting for forcing RTL layout, into a System Property
10973        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10974
10975        Configuration configuration = new Configuration();
10976        Settings.System.getConfiguration(resolver, configuration);
10977        if (forceRtl) {
10978            // This will take care of setting the correct layout direction flags
10979            configuration.setLayoutDirection(configuration.locale);
10980        }
10981
10982        synchronized (this) {
10983            mDebugApp = mOrigDebugApp = debugApp;
10984            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10985            mAlwaysFinishActivities = alwaysFinishActivities;
10986            // This happens before any activities are started, so we can
10987            // change mConfiguration in-place.
10988            updateConfigurationLocked(configuration, null, false, true);
10989            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10990        }
10991    }
10992
10993    /** Loads resources after the current configuration has been set. */
10994    private void loadResourcesOnSystemReady() {
10995        final Resources res = mContext.getResources();
10996        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10997        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10998        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10999    }
11000
11001    public boolean testIsSystemReady() {
11002        // no need to synchronize(this) just to read & return the value
11003        return mSystemReady;
11004    }
11005
11006    private static File getCalledPreBootReceiversFile() {
11007        File dataDir = Environment.getDataDirectory();
11008        File systemDir = new File(dataDir, "system");
11009        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11010        return fname;
11011    }
11012
11013    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11014        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11015        File file = getCalledPreBootReceiversFile();
11016        FileInputStream fis = null;
11017        try {
11018            fis = new FileInputStream(file);
11019            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11020            int fvers = dis.readInt();
11021            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11022                String vers = dis.readUTF();
11023                String codename = dis.readUTF();
11024                String build = dis.readUTF();
11025                if (android.os.Build.VERSION.RELEASE.equals(vers)
11026                        && android.os.Build.VERSION.CODENAME.equals(codename)
11027                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11028                    int num = dis.readInt();
11029                    while (num > 0) {
11030                        num--;
11031                        String pkg = dis.readUTF();
11032                        String cls = dis.readUTF();
11033                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11034                    }
11035                }
11036            }
11037        } catch (FileNotFoundException e) {
11038        } catch (IOException e) {
11039            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11040        } finally {
11041            if (fis != null) {
11042                try {
11043                    fis.close();
11044                } catch (IOException e) {
11045                }
11046            }
11047        }
11048        return lastDoneReceivers;
11049    }
11050
11051    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11052        File file = getCalledPreBootReceiversFile();
11053        FileOutputStream fos = null;
11054        DataOutputStream dos = null;
11055        try {
11056            fos = new FileOutputStream(file);
11057            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11058            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11059            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11060            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11061            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11062            dos.writeInt(list.size());
11063            for (int i=0; i<list.size(); i++) {
11064                dos.writeUTF(list.get(i).getPackageName());
11065                dos.writeUTF(list.get(i).getClassName());
11066            }
11067        } catch (IOException e) {
11068            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11069            file.delete();
11070        } finally {
11071            FileUtils.sync(fos);
11072            if (dos != null) {
11073                try {
11074                    dos.close();
11075                } catch (IOException e) {
11076                    // TODO Auto-generated catch block
11077                    e.printStackTrace();
11078                }
11079            }
11080        }
11081    }
11082
11083    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11084            ArrayList<ComponentName> doneReceivers, int userId) {
11085        boolean waitingUpdate = false;
11086        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11087        List<ResolveInfo> ris = null;
11088        try {
11089            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11090                    intent, null, 0, userId);
11091        } catch (RemoteException e) {
11092        }
11093        if (ris != null) {
11094            for (int i=ris.size()-1; i>=0; i--) {
11095                if ((ris.get(i).activityInfo.applicationInfo.flags
11096                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11097                    ris.remove(i);
11098                }
11099            }
11100            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11101
11102            // For User 0, load the version number. When delivering to a new user, deliver
11103            // to all receivers.
11104            if (userId == UserHandle.USER_OWNER) {
11105                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11106                for (int i=0; i<ris.size(); i++) {
11107                    ActivityInfo ai = ris.get(i).activityInfo;
11108                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11109                    if (lastDoneReceivers.contains(comp)) {
11110                        // We already did the pre boot receiver for this app with the current
11111                        // platform version, so don't do it again...
11112                        ris.remove(i);
11113                        i--;
11114                        // ...however, do keep it as one that has been done, so we don't
11115                        // forget about it when rewriting the file of last done receivers.
11116                        doneReceivers.add(comp);
11117                    }
11118                }
11119            }
11120
11121            // If primary user, send broadcast to all available users, else just to userId
11122            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11123                    : new int[] { userId };
11124            for (int i = 0; i < ris.size(); i++) {
11125                ActivityInfo ai = ris.get(i).activityInfo;
11126                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11127                doneReceivers.add(comp);
11128                intent.setComponent(comp);
11129                for (int j=0; j<users.length; j++) {
11130                    IIntentReceiver finisher = null;
11131                    // On last receiver and user, set up a completion callback
11132                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11133                        finisher = new IIntentReceiver.Stub() {
11134                            public void performReceive(Intent intent, int resultCode,
11135                                    String data, Bundle extras, boolean ordered,
11136                                    boolean sticky, int sendingUser) {
11137                                // The raw IIntentReceiver interface is called
11138                                // with the AM lock held, so redispatch to
11139                                // execute our code without the lock.
11140                                mHandler.post(onFinishCallback);
11141                            }
11142                        };
11143                    }
11144                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11145                            + " for user " + users[j]);
11146                    broadcastIntentLocked(null, null, intent, null, finisher,
11147                            0, null, null, null, AppOpsManager.OP_NONE,
11148                            true, false, MY_PID, Process.SYSTEM_UID,
11149                            users[j]);
11150                    if (finisher != null) {
11151                        waitingUpdate = true;
11152                    }
11153                }
11154            }
11155        }
11156
11157        return waitingUpdate;
11158    }
11159
11160    public void systemReady(final Runnable goingCallback) {
11161        synchronized(this) {
11162            if (mSystemReady) {
11163                // If we're done calling all the receivers, run the next "boot phase" passed in
11164                // by the SystemServer
11165                if (goingCallback != null) {
11166                    goingCallback.run();
11167                }
11168                return;
11169            }
11170
11171            // Make sure we have the current profile info, since it is needed for
11172            // security checks.
11173            updateCurrentProfileIdsLocked();
11174
11175            if (mRecentTasks == null) {
11176                mRecentTasks = mTaskPersister.restoreTasksLocked();
11177                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11178                if (!mRecentTasks.isEmpty()) {
11179                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11180                }
11181                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11182                mTaskPersister.startPersisting();
11183            }
11184
11185            // Check to see if there are any update receivers to run.
11186            if (!mDidUpdate) {
11187                if (mWaitingUpdate) {
11188                    return;
11189                }
11190                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11191                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11192                    public void run() {
11193                        synchronized (ActivityManagerService.this) {
11194                            mDidUpdate = true;
11195                        }
11196                        writeLastDonePreBootReceivers(doneReceivers);
11197                        showBootMessage(mContext.getText(
11198                                R.string.android_upgrading_complete),
11199                                false);
11200                        systemReady(goingCallback);
11201                    }
11202                }, doneReceivers, UserHandle.USER_OWNER);
11203
11204                if (mWaitingUpdate) {
11205                    return;
11206                }
11207                mDidUpdate = true;
11208            }
11209
11210            mAppOpsService.systemReady();
11211            mSystemReady = true;
11212        }
11213
11214        ArrayList<ProcessRecord> procsToKill = null;
11215        synchronized(mPidsSelfLocked) {
11216            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11217                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11218                if (!isAllowedWhileBooting(proc.info)){
11219                    if (procsToKill == null) {
11220                        procsToKill = new ArrayList<ProcessRecord>();
11221                    }
11222                    procsToKill.add(proc);
11223                }
11224            }
11225        }
11226
11227        synchronized(this) {
11228            if (procsToKill != null) {
11229                for (int i=procsToKill.size()-1; i>=0; i--) {
11230                    ProcessRecord proc = procsToKill.get(i);
11231                    Slog.i(TAG, "Removing system update proc: " + proc);
11232                    removeProcessLocked(proc, true, false, "system update done");
11233                }
11234            }
11235
11236            // Now that we have cleaned up any update processes, we
11237            // are ready to start launching real processes and know that
11238            // we won't trample on them any more.
11239            mProcessesReady = true;
11240        }
11241
11242        Slog.i(TAG, "System now ready");
11243        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11244            SystemClock.uptimeMillis());
11245
11246        synchronized(this) {
11247            // Make sure we have no pre-ready processes sitting around.
11248
11249            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11250                ResolveInfo ri = mContext.getPackageManager()
11251                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11252                                STOCK_PM_FLAGS);
11253                CharSequence errorMsg = null;
11254                if (ri != null) {
11255                    ActivityInfo ai = ri.activityInfo;
11256                    ApplicationInfo app = ai.applicationInfo;
11257                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11258                        mTopAction = Intent.ACTION_FACTORY_TEST;
11259                        mTopData = null;
11260                        mTopComponent = new ComponentName(app.packageName,
11261                                ai.name);
11262                    } else {
11263                        errorMsg = mContext.getResources().getText(
11264                                com.android.internal.R.string.factorytest_not_system);
11265                    }
11266                } else {
11267                    errorMsg = mContext.getResources().getText(
11268                            com.android.internal.R.string.factorytest_no_action);
11269                }
11270                if (errorMsg != null) {
11271                    mTopAction = null;
11272                    mTopData = null;
11273                    mTopComponent = null;
11274                    Message msg = Message.obtain();
11275                    msg.what = SHOW_FACTORY_ERROR_MSG;
11276                    msg.getData().putCharSequence("msg", errorMsg);
11277                    mHandler.sendMessage(msg);
11278                }
11279            }
11280        }
11281
11282        retrieveSettings();
11283        loadResourcesOnSystemReady();
11284
11285        synchronized (this) {
11286            readGrantedUriPermissionsLocked();
11287        }
11288
11289        if (goingCallback != null) goingCallback.run();
11290
11291        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11292                Integer.toString(mCurrentUserId), mCurrentUserId);
11293        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11294                Integer.toString(mCurrentUserId), mCurrentUserId);
11295        mSystemServiceManager.startUser(mCurrentUserId);
11296
11297        synchronized (this) {
11298            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11299                try {
11300                    List apps = AppGlobals.getPackageManager().
11301                        getPersistentApplications(STOCK_PM_FLAGS);
11302                    if (apps != null) {
11303                        int N = apps.size();
11304                        int i;
11305                        for (i=0; i<N; i++) {
11306                            ApplicationInfo info
11307                                = (ApplicationInfo)apps.get(i);
11308                            if (info != null &&
11309                                    !info.packageName.equals("android")) {
11310                                addAppLocked(info, false, null /* ABI override */);
11311                            }
11312                        }
11313                    }
11314                } catch (RemoteException ex) {
11315                    // pm is in same process, this will never happen.
11316                }
11317            }
11318
11319            // Start up initial activity.
11320            mBooting = true;
11321            startHomeActivityLocked(mCurrentUserId);
11322
11323            try {
11324                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11325                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11326                            + " data partition or your device will be unstable.");
11327                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11328                }
11329            } catch (RemoteException e) {
11330            }
11331
11332            if (!Build.isFingerprintConsistent()) {
11333                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11334                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11335            }
11336
11337            long ident = Binder.clearCallingIdentity();
11338            try {
11339                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11340                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11341                        | Intent.FLAG_RECEIVER_FOREGROUND);
11342                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11343                broadcastIntentLocked(null, null, intent,
11344                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11345                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11346                intent = new Intent(Intent.ACTION_USER_STARTING);
11347                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11348                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11349                broadcastIntentLocked(null, null, intent,
11350                        null, new IIntentReceiver.Stub() {
11351                            @Override
11352                            public void performReceive(Intent intent, int resultCode, String data,
11353                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11354                                    throws RemoteException {
11355                            }
11356                        }, 0, null, null,
11357                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11358                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11359            } catch (Throwable t) {
11360                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11361            } finally {
11362                Binder.restoreCallingIdentity(ident);
11363            }
11364            mStackSupervisor.resumeTopActivitiesLocked();
11365            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11366        }
11367    }
11368
11369    private boolean makeAppCrashingLocked(ProcessRecord app,
11370            String shortMsg, String longMsg, String stackTrace) {
11371        app.crashing = true;
11372        app.crashingReport = generateProcessError(app,
11373                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11374        startAppProblemLocked(app);
11375        app.stopFreezingAllLocked();
11376        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11377    }
11378
11379    private void makeAppNotRespondingLocked(ProcessRecord app,
11380            String activity, String shortMsg, String longMsg) {
11381        app.notResponding = true;
11382        app.notRespondingReport = generateProcessError(app,
11383                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11384                activity, shortMsg, longMsg, null);
11385        startAppProblemLocked(app);
11386        app.stopFreezingAllLocked();
11387    }
11388
11389    /**
11390     * Generate a process error record, suitable for attachment to a ProcessRecord.
11391     *
11392     * @param app The ProcessRecord in which the error occurred.
11393     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11394     *                      ActivityManager.AppErrorStateInfo
11395     * @param activity The activity associated with the crash, if known.
11396     * @param shortMsg Short message describing the crash.
11397     * @param longMsg Long message describing the crash.
11398     * @param stackTrace Full crash stack trace, may be null.
11399     *
11400     * @return Returns a fully-formed AppErrorStateInfo record.
11401     */
11402    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11403            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11404        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11405
11406        report.condition = condition;
11407        report.processName = app.processName;
11408        report.pid = app.pid;
11409        report.uid = app.info.uid;
11410        report.tag = activity;
11411        report.shortMsg = shortMsg;
11412        report.longMsg = longMsg;
11413        report.stackTrace = stackTrace;
11414
11415        return report;
11416    }
11417
11418    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11419        synchronized (this) {
11420            app.crashing = false;
11421            app.crashingReport = null;
11422            app.notResponding = false;
11423            app.notRespondingReport = null;
11424            if (app.anrDialog == fromDialog) {
11425                app.anrDialog = null;
11426            }
11427            if (app.waitDialog == fromDialog) {
11428                app.waitDialog = null;
11429            }
11430            if (app.pid > 0 && app.pid != MY_PID) {
11431                handleAppCrashLocked(app, null, null, null);
11432                app.kill("user request after error", true);
11433            }
11434        }
11435    }
11436
11437    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11438            String stackTrace) {
11439        long now = SystemClock.uptimeMillis();
11440
11441        Long crashTime;
11442        if (!app.isolated) {
11443            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11444        } else {
11445            crashTime = null;
11446        }
11447        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11448            // This process loses!
11449            Slog.w(TAG, "Process " + app.info.processName
11450                    + " has crashed too many times: killing!");
11451            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11452                    app.userId, app.info.processName, app.uid);
11453            mStackSupervisor.handleAppCrashLocked(app);
11454            if (!app.persistent) {
11455                // We don't want to start this process again until the user
11456                // explicitly does so...  but for persistent process, we really
11457                // need to keep it running.  If a persistent process is actually
11458                // repeatedly crashing, then badness for everyone.
11459                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11460                        app.info.processName);
11461                if (!app.isolated) {
11462                    // XXX We don't have a way to mark isolated processes
11463                    // as bad, since they don't have a peristent identity.
11464                    mBadProcesses.put(app.info.processName, app.uid,
11465                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11466                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11467                }
11468                app.bad = true;
11469                app.removed = true;
11470                // Don't let services in this process be restarted and potentially
11471                // annoy the user repeatedly.  Unless it is persistent, since those
11472                // processes run critical code.
11473                removeProcessLocked(app, false, false, "crash");
11474                mStackSupervisor.resumeTopActivitiesLocked();
11475                return false;
11476            }
11477            mStackSupervisor.resumeTopActivitiesLocked();
11478        } else {
11479            mStackSupervisor.finishTopRunningActivityLocked(app);
11480        }
11481
11482        // Bump up the crash count of any services currently running in the proc.
11483        for (int i=app.services.size()-1; i>=0; i--) {
11484            // Any services running in the application need to be placed
11485            // back in the pending list.
11486            ServiceRecord sr = app.services.valueAt(i);
11487            sr.crashCount++;
11488        }
11489
11490        // If the crashing process is what we consider to be the "home process" and it has been
11491        // replaced by a third-party app, clear the package preferred activities from packages
11492        // with a home activity running in the process to prevent a repeatedly crashing app
11493        // from blocking the user to manually clear the list.
11494        final ArrayList<ActivityRecord> activities = app.activities;
11495        if (app == mHomeProcess && activities.size() > 0
11496                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11497            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11498                final ActivityRecord r = activities.get(activityNdx);
11499                if (r.isHomeActivity()) {
11500                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11501                    try {
11502                        ActivityThread.getPackageManager()
11503                                .clearPackagePreferredActivities(r.packageName);
11504                    } catch (RemoteException c) {
11505                        // pm is in same process, this will never happen.
11506                    }
11507                }
11508            }
11509        }
11510
11511        if (!app.isolated) {
11512            // XXX Can't keep track of crash times for isolated processes,
11513            // because they don't have a perisistent identity.
11514            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11515        }
11516
11517        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11518        return true;
11519    }
11520
11521    void startAppProblemLocked(ProcessRecord app) {
11522        // If this app is not running under the current user, then we
11523        // can't give it a report button because that would require
11524        // launching the report UI under a different user.
11525        app.errorReportReceiver = null;
11526
11527        for (int userId : mCurrentProfileIds) {
11528            if (app.userId == userId) {
11529                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11530                        mContext, app.info.packageName, app.info.flags);
11531            }
11532        }
11533        skipCurrentReceiverLocked(app);
11534    }
11535
11536    void skipCurrentReceiverLocked(ProcessRecord app) {
11537        for (BroadcastQueue queue : mBroadcastQueues) {
11538            queue.skipCurrentReceiverLocked(app);
11539        }
11540    }
11541
11542    /**
11543     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11544     * The application process will exit immediately after this call returns.
11545     * @param app object of the crashing app, null for the system server
11546     * @param crashInfo describing the exception
11547     */
11548    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11549        ProcessRecord r = findAppProcess(app, "Crash");
11550        final String processName = app == null ? "system_server"
11551                : (r == null ? "unknown" : r.processName);
11552
11553        handleApplicationCrashInner("crash", r, processName, crashInfo);
11554    }
11555
11556    /* Native crash reporting uses this inner version because it needs to be somewhat
11557     * decoupled from the AM-managed cleanup lifecycle
11558     */
11559    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11560            ApplicationErrorReport.CrashInfo crashInfo) {
11561        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11562                UserHandle.getUserId(Binder.getCallingUid()), processName,
11563                r == null ? -1 : r.info.flags,
11564                crashInfo.exceptionClassName,
11565                crashInfo.exceptionMessage,
11566                crashInfo.throwFileName,
11567                crashInfo.throwLineNumber);
11568
11569        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11570
11571        crashApplication(r, crashInfo);
11572    }
11573
11574    public void handleApplicationStrictModeViolation(
11575            IBinder app,
11576            int violationMask,
11577            StrictMode.ViolationInfo info) {
11578        ProcessRecord r = findAppProcess(app, "StrictMode");
11579        if (r == null) {
11580            return;
11581        }
11582
11583        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11584            Integer stackFingerprint = info.hashCode();
11585            boolean logIt = true;
11586            synchronized (mAlreadyLoggedViolatedStacks) {
11587                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11588                    logIt = false;
11589                    // TODO: sub-sample into EventLog for these, with
11590                    // the info.durationMillis?  Then we'd get
11591                    // the relative pain numbers, without logging all
11592                    // the stack traces repeatedly.  We'd want to do
11593                    // likewise in the client code, which also does
11594                    // dup suppression, before the Binder call.
11595                } else {
11596                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11597                        mAlreadyLoggedViolatedStacks.clear();
11598                    }
11599                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11600                }
11601            }
11602            if (logIt) {
11603                logStrictModeViolationToDropBox(r, info);
11604            }
11605        }
11606
11607        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11608            AppErrorResult result = new AppErrorResult();
11609            synchronized (this) {
11610                final long origId = Binder.clearCallingIdentity();
11611
11612                Message msg = Message.obtain();
11613                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11614                HashMap<String, Object> data = new HashMap<String, Object>();
11615                data.put("result", result);
11616                data.put("app", r);
11617                data.put("violationMask", violationMask);
11618                data.put("info", info);
11619                msg.obj = data;
11620                mHandler.sendMessage(msg);
11621
11622                Binder.restoreCallingIdentity(origId);
11623            }
11624            int res = result.get();
11625            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11626        }
11627    }
11628
11629    // Depending on the policy in effect, there could be a bunch of
11630    // these in quick succession so we try to batch these together to
11631    // minimize disk writes, number of dropbox entries, and maximize
11632    // compression, by having more fewer, larger records.
11633    private void logStrictModeViolationToDropBox(
11634            ProcessRecord process,
11635            StrictMode.ViolationInfo info) {
11636        if (info == null) {
11637            return;
11638        }
11639        final boolean isSystemApp = process == null ||
11640                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11641                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11642        final String processName = process == null ? "unknown" : process.processName;
11643        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11644        final DropBoxManager dbox = (DropBoxManager)
11645                mContext.getSystemService(Context.DROPBOX_SERVICE);
11646
11647        // Exit early if the dropbox isn't configured to accept this report type.
11648        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11649
11650        boolean bufferWasEmpty;
11651        boolean needsFlush;
11652        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11653        synchronized (sb) {
11654            bufferWasEmpty = sb.length() == 0;
11655            appendDropBoxProcessHeaders(process, processName, sb);
11656            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11657            sb.append("System-App: ").append(isSystemApp).append("\n");
11658            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11659            if (info.violationNumThisLoop != 0) {
11660                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11661            }
11662            if (info.numAnimationsRunning != 0) {
11663                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11664            }
11665            if (info.broadcastIntentAction != null) {
11666                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11667            }
11668            if (info.durationMillis != -1) {
11669                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11670            }
11671            if (info.numInstances != -1) {
11672                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11673            }
11674            if (info.tags != null) {
11675                for (String tag : info.tags) {
11676                    sb.append("Span-Tag: ").append(tag).append("\n");
11677                }
11678            }
11679            sb.append("\n");
11680            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11681                sb.append(info.crashInfo.stackTrace);
11682            }
11683            sb.append("\n");
11684
11685            // Only buffer up to ~64k.  Various logging bits truncate
11686            // things at 128k.
11687            needsFlush = (sb.length() > 64 * 1024);
11688        }
11689
11690        // Flush immediately if the buffer's grown too large, or this
11691        // is a non-system app.  Non-system apps are isolated with a
11692        // different tag & policy and not batched.
11693        //
11694        // Batching is useful during internal testing with
11695        // StrictMode settings turned up high.  Without batching,
11696        // thousands of separate files could be created on boot.
11697        if (!isSystemApp || needsFlush) {
11698            new Thread("Error dump: " + dropboxTag) {
11699                @Override
11700                public void run() {
11701                    String report;
11702                    synchronized (sb) {
11703                        report = sb.toString();
11704                        sb.delete(0, sb.length());
11705                        sb.trimToSize();
11706                    }
11707                    if (report.length() != 0) {
11708                        dbox.addText(dropboxTag, report);
11709                    }
11710                }
11711            }.start();
11712            return;
11713        }
11714
11715        // System app batching:
11716        if (!bufferWasEmpty) {
11717            // An existing dropbox-writing thread is outstanding, so
11718            // we don't need to start it up.  The existing thread will
11719            // catch the buffer appends we just did.
11720            return;
11721        }
11722
11723        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11724        // (After this point, we shouldn't access AMS internal data structures.)
11725        new Thread("Error dump: " + dropboxTag) {
11726            @Override
11727            public void run() {
11728                // 5 second sleep to let stacks arrive and be batched together
11729                try {
11730                    Thread.sleep(5000);  // 5 seconds
11731                } catch (InterruptedException e) {}
11732
11733                String errorReport;
11734                synchronized (mStrictModeBuffer) {
11735                    errorReport = mStrictModeBuffer.toString();
11736                    if (errorReport.length() == 0) {
11737                        return;
11738                    }
11739                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11740                    mStrictModeBuffer.trimToSize();
11741                }
11742                dbox.addText(dropboxTag, errorReport);
11743            }
11744        }.start();
11745    }
11746
11747    /**
11748     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11749     * @param app object of the crashing app, null for the system server
11750     * @param tag reported by the caller
11751     * @param system whether this wtf is coming from the system
11752     * @param crashInfo describing the context of the error
11753     * @return true if the process should exit immediately (WTF is fatal)
11754     */
11755    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11756            final ApplicationErrorReport.CrashInfo crashInfo) {
11757        final int callingUid = Binder.getCallingUid();
11758        final int callingPid = Binder.getCallingPid();
11759
11760        if (system) {
11761            // If this is coming from the system, we could very well have low-level
11762            // system locks held, so we want to do this all asynchronously.  And we
11763            // never want this to become fatal, so there is that too.
11764            mHandler.post(new Runnable() {
11765                @Override public void run() {
11766                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11767                }
11768            });
11769            return false;
11770        }
11771
11772        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11773                crashInfo);
11774
11775        if (r != null && r.pid != Process.myPid() &&
11776                Settings.Global.getInt(mContext.getContentResolver(),
11777                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11778            crashApplication(r, crashInfo);
11779            return true;
11780        } else {
11781            return false;
11782        }
11783    }
11784
11785    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11786            final ApplicationErrorReport.CrashInfo crashInfo) {
11787        final ProcessRecord r = findAppProcess(app, "WTF");
11788        final String processName = app == null ? "system_server"
11789                : (r == null ? "unknown" : r.processName);
11790
11791        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11792                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11793
11794        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11795
11796        return r;
11797    }
11798
11799    /**
11800     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11801     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11802     */
11803    private ProcessRecord findAppProcess(IBinder app, String reason) {
11804        if (app == null) {
11805            return null;
11806        }
11807
11808        synchronized (this) {
11809            final int NP = mProcessNames.getMap().size();
11810            for (int ip=0; ip<NP; ip++) {
11811                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11812                final int NA = apps.size();
11813                for (int ia=0; ia<NA; ia++) {
11814                    ProcessRecord p = apps.valueAt(ia);
11815                    if (p.thread != null && p.thread.asBinder() == app) {
11816                        return p;
11817                    }
11818                }
11819            }
11820
11821            Slog.w(TAG, "Can't find mystery application for " + reason
11822                    + " from pid=" + Binder.getCallingPid()
11823                    + " uid=" + Binder.getCallingUid() + ": " + app);
11824            return null;
11825        }
11826    }
11827
11828    /**
11829     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11830     * to append various headers to the dropbox log text.
11831     */
11832    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11833            StringBuilder sb) {
11834        // Watchdog thread ends up invoking this function (with
11835        // a null ProcessRecord) to add the stack file to dropbox.
11836        // Do not acquire a lock on this (am) in such cases, as it
11837        // could cause a potential deadlock, if and when watchdog
11838        // is invoked due to unavailability of lock on am and it
11839        // would prevent watchdog from killing system_server.
11840        if (process == null) {
11841            sb.append("Process: ").append(processName).append("\n");
11842            return;
11843        }
11844        // Note: ProcessRecord 'process' is guarded by the service
11845        // instance.  (notably process.pkgList, which could otherwise change
11846        // concurrently during execution of this method)
11847        synchronized (this) {
11848            sb.append("Process: ").append(processName).append("\n");
11849            int flags = process.info.flags;
11850            IPackageManager pm = AppGlobals.getPackageManager();
11851            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11852            for (int ip=0; ip<process.pkgList.size(); ip++) {
11853                String pkg = process.pkgList.keyAt(ip);
11854                sb.append("Package: ").append(pkg);
11855                try {
11856                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11857                    if (pi != null) {
11858                        sb.append(" v").append(pi.versionCode);
11859                        if (pi.versionName != null) {
11860                            sb.append(" (").append(pi.versionName).append(")");
11861                        }
11862                    }
11863                } catch (RemoteException e) {
11864                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11865                }
11866                sb.append("\n");
11867            }
11868        }
11869    }
11870
11871    private static String processClass(ProcessRecord process) {
11872        if (process == null || process.pid == MY_PID) {
11873            return "system_server";
11874        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11875            return "system_app";
11876        } else {
11877            return "data_app";
11878        }
11879    }
11880
11881    /**
11882     * Write a description of an error (crash, WTF, ANR) to the drop box.
11883     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11884     * @param process which caused the error, null means the system server
11885     * @param activity which triggered the error, null if unknown
11886     * @param parent activity related to the error, null if unknown
11887     * @param subject line related to the error, null if absent
11888     * @param report in long form describing the error, null if absent
11889     * @param logFile to include in the report, null if none
11890     * @param crashInfo giving an application stack trace, null if absent
11891     */
11892    public void addErrorToDropBox(String eventType,
11893            ProcessRecord process, String processName, ActivityRecord activity,
11894            ActivityRecord parent, String subject,
11895            final String report, final File logFile,
11896            final ApplicationErrorReport.CrashInfo crashInfo) {
11897        // NOTE -- this must never acquire the ActivityManagerService lock,
11898        // otherwise the watchdog may be prevented from resetting the system.
11899
11900        final String dropboxTag = processClass(process) + "_" + eventType;
11901        final DropBoxManager dbox = (DropBoxManager)
11902                mContext.getSystemService(Context.DROPBOX_SERVICE);
11903
11904        // Exit early if the dropbox isn't configured to accept this report type.
11905        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11906
11907        final StringBuilder sb = new StringBuilder(1024);
11908        appendDropBoxProcessHeaders(process, processName, sb);
11909        if (activity != null) {
11910            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11911        }
11912        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11913            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11914        }
11915        if (parent != null && parent != activity) {
11916            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11917        }
11918        if (subject != null) {
11919            sb.append("Subject: ").append(subject).append("\n");
11920        }
11921        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11922        if (Debug.isDebuggerConnected()) {
11923            sb.append("Debugger: Connected\n");
11924        }
11925        sb.append("\n");
11926
11927        // Do the rest in a worker thread to avoid blocking the caller on I/O
11928        // (After this point, we shouldn't access AMS internal data structures.)
11929        Thread worker = new Thread("Error dump: " + dropboxTag) {
11930            @Override
11931            public void run() {
11932                if (report != null) {
11933                    sb.append(report);
11934                }
11935                if (logFile != null) {
11936                    try {
11937                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11938                                    "\n\n[[TRUNCATED]]"));
11939                    } catch (IOException e) {
11940                        Slog.e(TAG, "Error reading " + logFile, e);
11941                    }
11942                }
11943                if (crashInfo != null && crashInfo.stackTrace != null) {
11944                    sb.append(crashInfo.stackTrace);
11945                }
11946
11947                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11948                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11949                if (lines > 0) {
11950                    sb.append("\n");
11951
11952                    // Merge several logcat streams, and take the last N lines
11953                    InputStreamReader input = null;
11954                    try {
11955                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11956                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11957                                "-b", "crash",
11958                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11959
11960                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11961                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11962                        input = new InputStreamReader(logcat.getInputStream());
11963
11964                        int num;
11965                        char[] buf = new char[8192];
11966                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11967                    } catch (IOException e) {
11968                        Slog.e(TAG, "Error running logcat", e);
11969                    } finally {
11970                        if (input != null) try { input.close(); } catch (IOException e) {}
11971                    }
11972                }
11973
11974                dbox.addText(dropboxTag, sb.toString());
11975            }
11976        };
11977
11978        if (process == null) {
11979            // If process is null, we are being called from some internal code
11980            // and may be about to die -- run this synchronously.
11981            worker.run();
11982        } else {
11983            worker.start();
11984        }
11985    }
11986
11987    /**
11988     * Bring up the "unexpected error" dialog box for a crashing app.
11989     * Deal with edge cases (intercepts from instrumented applications,
11990     * ActivityController, error intent receivers, that sort of thing).
11991     * @param r the application crashing
11992     * @param crashInfo describing the failure
11993     */
11994    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11995        long timeMillis = System.currentTimeMillis();
11996        String shortMsg = crashInfo.exceptionClassName;
11997        String longMsg = crashInfo.exceptionMessage;
11998        String stackTrace = crashInfo.stackTrace;
11999        if (shortMsg != null && longMsg != null) {
12000            longMsg = shortMsg + ": " + longMsg;
12001        } else if (shortMsg != null) {
12002            longMsg = shortMsg;
12003        }
12004
12005        AppErrorResult result = new AppErrorResult();
12006        synchronized (this) {
12007            if (mController != null) {
12008                try {
12009                    String name = r != null ? r.processName : null;
12010                    int pid = r != null ? r.pid : Binder.getCallingPid();
12011                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12012                    if (!mController.appCrashed(name, pid,
12013                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12014                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12015                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12016                            Slog.w(TAG, "Skip killing native crashed app " + name
12017                                    + "(" + pid + ") during testing");
12018                        } else {
12019                            Slog.w(TAG, "Force-killing crashed app " + name
12020                                    + " at watcher's request");
12021                            if (r != null) {
12022                                r.kill("crash", true);
12023                            } else {
12024                                // Huh.
12025                                Process.killProcess(pid);
12026                                Process.killProcessGroup(uid, pid);
12027                            }
12028                        }
12029                        return;
12030                    }
12031                } catch (RemoteException e) {
12032                    mController = null;
12033                    Watchdog.getInstance().setActivityController(null);
12034                }
12035            }
12036
12037            final long origId = Binder.clearCallingIdentity();
12038
12039            // If this process is running instrumentation, finish it.
12040            if (r != null && r.instrumentationClass != null) {
12041                Slog.w(TAG, "Error in app " + r.processName
12042                      + " running instrumentation " + r.instrumentationClass + ":");
12043                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12044                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12045                Bundle info = new Bundle();
12046                info.putString("shortMsg", shortMsg);
12047                info.putString("longMsg", longMsg);
12048                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12049                Binder.restoreCallingIdentity(origId);
12050                return;
12051            }
12052
12053            // Log crash in battery stats.
12054            if (r != null) {
12055                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12056            }
12057
12058            // If we can't identify the process or it's already exceeded its crash quota,
12059            // quit right away without showing a crash dialog.
12060            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12061                Binder.restoreCallingIdentity(origId);
12062                return;
12063            }
12064
12065            Message msg = Message.obtain();
12066            msg.what = SHOW_ERROR_MSG;
12067            HashMap data = new HashMap();
12068            data.put("result", result);
12069            data.put("app", r);
12070            msg.obj = data;
12071            mHandler.sendMessage(msg);
12072
12073            Binder.restoreCallingIdentity(origId);
12074        }
12075
12076        int res = result.get();
12077
12078        Intent appErrorIntent = null;
12079        synchronized (this) {
12080            if (r != null && !r.isolated) {
12081                // XXX Can't keep track of crash time for isolated processes,
12082                // since they don't have a persistent identity.
12083                mProcessCrashTimes.put(r.info.processName, r.uid,
12084                        SystemClock.uptimeMillis());
12085            }
12086            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12087                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12088            }
12089        }
12090
12091        if (appErrorIntent != null) {
12092            try {
12093                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12094            } catch (ActivityNotFoundException e) {
12095                Slog.w(TAG, "bug report receiver dissappeared", e);
12096            }
12097        }
12098    }
12099
12100    Intent createAppErrorIntentLocked(ProcessRecord r,
12101            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12102        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12103        if (report == null) {
12104            return null;
12105        }
12106        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12107        result.setComponent(r.errorReportReceiver);
12108        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12109        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12110        return result;
12111    }
12112
12113    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12114            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12115        if (r.errorReportReceiver == null) {
12116            return null;
12117        }
12118
12119        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12120            return null;
12121        }
12122
12123        ApplicationErrorReport report = new ApplicationErrorReport();
12124        report.packageName = r.info.packageName;
12125        report.installerPackageName = r.errorReportReceiver.getPackageName();
12126        report.processName = r.processName;
12127        report.time = timeMillis;
12128        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12129
12130        if (r.crashing || r.forceCrashReport) {
12131            report.type = ApplicationErrorReport.TYPE_CRASH;
12132            report.crashInfo = crashInfo;
12133        } else if (r.notResponding) {
12134            report.type = ApplicationErrorReport.TYPE_ANR;
12135            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12136
12137            report.anrInfo.activity = r.notRespondingReport.tag;
12138            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12139            report.anrInfo.info = r.notRespondingReport.longMsg;
12140        }
12141
12142        return report;
12143    }
12144
12145    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12146        enforceNotIsolatedCaller("getProcessesInErrorState");
12147        // assume our apps are happy - lazy create the list
12148        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12149
12150        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12151                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12152        int userId = UserHandle.getUserId(Binder.getCallingUid());
12153
12154        synchronized (this) {
12155
12156            // iterate across all processes
12157            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12158                ProcessRecord app = mLruProcesses.get(i);
12159                if (!allUsers && app.userId != userId) {
12160                    continue;
12161                }
12162                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12163                    // This one's in trouble, so we'll generate a report for it
12164                    // crashes are higher priority (in case there's a crash *and* an anr)
12165                    ActivityManager.ProcessErrorStateInfo report = null;
12166                    if (app.crashing) {
12167                        report = app.crashingReport;
12168                    } else if (app.notResponding) {
12169                        report = app.notRespondingReport;
12170                    }
12171
12172                    if (report != null) {
12173                        if (errList == null) {
12174                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12175                        }
12176                        errList.add(report);
12177                    } else {
12178                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12179                                " crashing = " + app.crashing +
12180                                " notResponding = " + app.notResponding);
12181                    }
12182                }
12183            }
12184        }
12185
12186        return errList;
12187    }
12188
12189    static int procStateToImportance(int procState, int memAdj,
12190            ActivityManager.RunningAppProcessInfo currApp) {
12191        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12192        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12193            currApp.lru = memAdj;
12194        } else {
12195            currApp.lru = 0;
12196        }
12197        return imp;
12198    }
12199
12200    private void fillInProcMemInfo(ProcessRecord app,
12201            ActivityManager.RunningAppProcessInfo outInfo) {
12202        outInfo.pid = app.pid;
12203        outInfo.uid = app.info.uid;
12204        if (mHeavyWeightProcess == app) {
12205            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12206        }
12207        if (app.persistent) {
12208            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12209        }
12210        if (app.activities.size() > 0) {
12211            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12212        }
12213        outInfo.lastTrimLevel = app.trimMemoryLevel;
12214        int adj = app.curAdj;
12215        int procState = app.curProcState;
12216        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12217        outInfo.importanceReasonCode = app.adjTypeCode;
12218        outInfo.processState = app.curProcState;
12219    }
12220
12221    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12222        enforceNotIsolatedCaller("getRunningAppProcesses");
12223        // Lazy instantiation of list
12224        List<ActivityManager.RunningAppProcessInfo> runList = null;
12225        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12226                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12227        int userId = UserHandle.getUserId(Binder.getCallingUid());
12228        synchronized (this) {
12229            // Iterate across all processes
12230            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12231                ProcessRecord app = mLruProcesses.get(i);
12232                if (!allUsers && app.userId != userId) {
12233                    continue;
12234                }
12235                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12236                    // Generate process state info for running application
12237                    ActivityManager.RunningAppProcessInfo currApp =
12238                        new ActivityManager.RunningAppProcessInfo(app.processName,
12239                                app.pid, app.getPackageList());
12240                    fillInProcMemInfo(app, currApp);
12241                    if (app.adjSource instanceof ProcessRecord) {
12242                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12243                        currApp.importanceReasonImportance =
12244                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12245                                        app.adjSourceProcState);
12246                    } else if (app.adjSource instanceof ActivityRecord) {
12247                        ActivityRecord r = (ActivityRecord)app.adjSource;
12248                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12249                    }
12250                    if (app.adjTarget instanceof ComponentName) {
12251                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12252                    }
12253                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12254                    //        + " lru=" + currApp.lru);
12255                    if (runList == null) {
12256                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12257                    }
12258                    runList.add(currApp);
12259                }
12260            }
12261        }
12262        return runList;
12263    }
12264
12265    public List<ApplicationInfo> getRunningExternalApplications() {
12266        enforceNotIsolatedCaller("getRunningExternalApplications");
12267        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12268        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12269        if (runningApps != null && runningApps.size() > 0) {
12270            Set<String> extList = new HashSet<String>();
12271            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12272                if (app.pkgList != null) {
12273                    for (String pkg : app.pkgList) {
12274                        extList.add(pkg);
12275                    }
12276                }
12277            }
12278            IPackageManager pm = AppGlobals.getPackageManager();
12279            for (String pkg : extList) {
12280                try {
12281                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12282                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12283                        retList.add(info);
12284                    }
12285                } catch (RemoteException e) {
12286                }
12287            }
12288        }
12289        return retList;
12290    }
12291
12292    @Override
12293    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12294        enforceNotIsolatedCaller("getMyMemoryState");
12295        synchronized (this) {
12296            ProcessRecord proc;
12297            synchronized (mPidsSelfLocked) {
12298                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12299            }
12300            fillInProcMemInfo(proc, outInfo);
12301        }
12302    }
12303
12304    @Override
12305    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12306        if (checkCallingPermission(android.Manifest.permission.DUMP)
12307                != PackageManager.PERMISSION_GRANTED) {
12308            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12309                    + Binder.getCallingPid()
12310                    + ", uid=" + Binder.getCallingUid()
12311                    + " without permission "
12312                    + android.Manifest.permission.DUMP);
12313            return;
12314        }
12315
12316        boolean dumpAll = false;
12317        boolean dumpClient = false;
12318        String dumpPackage = null;
12319
12320        int opti = 0;
12321        while (opti < args.length) {
12322            String opt = args[opti];
12323            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12324                break;
12325            }
12326            opti++;
12327            if ("-a".equals(opt)) {
12328                dumpAll = true;
12329            } else if ("-c".equals(opt)) {
12330                dumpClient = true;
12331            } else if ("-h".equals(opt)) {
12332                pw.println("Activity manager dump options:");
12333                pw.println("  [-a] [-c] [-h] [cmd] ...");
12334                pw.println("  cmd may be one of:");
12335                pw.println("    a[ctivities]: activity stack state");
12336                pw.println("    r[recents]: recent activities state");
12337                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12338                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12339                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12340                pw.println("    o[om]: out of memory management");
12341                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12342                pw.println("    provider [COMP_SPEC]: provider client-side state");
12343                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12344                pw.println("    service [COMP_SPEC]: service client-side state");
12345                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12346                pw.println("    all: dump all activities");
12347                pw.println("    top: dump the top activity");
12348                pw.println("    write: write all pending state to storage");
12349                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12350                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12351                pw.println("    a partial substring in a component name, a");
12352                pw.println("    hex object identifier.");
12353                pw.println("  -a: include all available server state.");
12354                pw.println("  -c: include client state.");
12355                return;
12356            } else {
12357                pw.println("Unknown argument: " + opt + "; use -h for help");
12358            }
12359        }
12360
12361        long origId = Binder.clearCallingIdentity();
12362        boolean more = false;
12363        // Is the caller requesting to dump a particular piece of data?
12364        if (opti < args.length) {
12365            String cmd = args[opti];
12366            opti++;
12367            if ("activities".equals(cmd) || "a".equals(cmd)) {
12368                synchronized (this) {
12369                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12370                }
12371            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12372                synchronized (this) {
12373                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12374                }
12375            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12376                String[] newArgs;
12377                String name;
12378                if (opti >= args.length) {
12379                    name = null;
12380                    newArgs = EMPTY_STRING_ARRAY;
12381                } else {
12382                    name = args[opti];
12383                    opti++;
12384                    newArgs = new String[args.length - opti];
12385                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12386                            args.length - opti);
12387                }
12388                synchronized (this) {
12389                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12390                }
12391            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12392                String[] newArgs;
12393                String name;
12394                if (opti >= args.length) {
12395                    name = null;
12396                    newArgs = EMPTY_STRING_ARRAY;
12397                } else {
12398                    name = args[opti];
12399                    opti++;
12400                    newArgs = new String[args.length - opti];
12401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12402                            args.length - opti);
12403                }
12404                synchronized (this) {
12405                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12406                }
12407            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12408                String[] newArgs;
12409                String name;
12410                if (opti >= args.length) {
12411                    name = null;
12412                    newArgs = EMPTY_STRING_ARRAY;
12413                } else {
12414                    name = args[opti];
12415                    opti++;
12416                    newArgs = new String[args.length - opti];
12417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12418                            args.length - opti);
12419                }
12420                synchronized (this) {
12421                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12422                }
12423            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12424                synchronized (this) {
12425                    dumpOomLocked(fd, pw, args, opti, true);
12426                }
12427            } else if ("provider".equals(cmd)) {
12428                String[] newArgs;
12429                String name;
12430                if (opti >= args.length) {
12431                    name = null;
12432                    newArgs = EMPTY_STRING_ARRAY;
12433                } else {
12434                    name = args[opti];
12435                    opti++;
12436                    newArgs = new String[args.length - opti];
12437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12438                }
12439                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12440                    pw.println("No providers match: " + name);
12441                    pw.println("Use -h for help.");
12442                }
12443            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12444                synchronized (this) {
12445                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12446                }
12447            } else if ("service".equals(cmd)) {
12448                String[] newArgs;
12449                String name;
12450                if (opti >= args.length) {
12451                    name = null;
12452                    newArgs = EMPTY_STRING_ARRAY;
12453                } else {
12454                    name = args[opti];
12455                    opti++;
12456                    newArgs = new String[args.length - opti];
12457                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12458                            args.length - opti);
12459                }
12460                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12461                    pw.println("No services match: " + name);
12462                    pw.println("Use -h for help.");
12463                }
12464            } else if ("package".equals(cmd)) {
12465                String[] newArgs;
12466                if (opti >= args.length) {
12467                    pw.println("package: no package name specified");
12468                    pw.println("Use -h for help.");
12469                } else {
12470                    dumpPackage = args[opti];
12471                    opti++;
12472                    newArgs = new String[args.length - opti];
12473                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12474                            args.length - opti);
12475                    args = newArgs;
12476                    opti = 0;
12477                    more = true;
12478                }
12479            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12480                synchronized (this) {
12481                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12482                }
12483            } else if ("write".equals(cmd)) {
12484                mTaskPersister.flush();
12485                pw.println("All tasks persisted.");
12486                return;
12487            } else {
12488                // Dumping a single activity?
12489                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12490                    pw.println("Bad activity command, or no activities match: " + cmd);
12491                    pw.println("Use -h for help.");
12492                }
12493            }
12494            if (!more) {
12495                Binder.restoreCallingIdentity(origId);
12496                return;
12497            }
12498        }
12499
12500        // No piece of data specified, dump everything.
12501        synchronized (this) {
12502            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12503            pw.println();
12504            if (dumpAll) {
12505                pw.println("-------------------------------------------------------------------------------");
12506            }
12507            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12508            pw.println();
12509            if (dumpAll) {
12510                pw.println("-------------------------------------------------------------------------------");
12511            }
12512            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12513            pw.println();
12514            if (dumpAll) {
12515                pw.println("-------------------------------------------------------------------------------");
12516            }
12517            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12518            pw.println();
12519            if (dumpAll) {
12520                pw.println("-------------------------------------------------------------------------------");
12521            }
12522            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12523            pw.println();
12524            if (dumpAll) {
12525                pw.println("-------------------------------------------------------------------------------");
12526            }
12527            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12528            pw.println();
12529            if (dumpAll) {
12530                pw.println("-------------------------------------------------------------------------------");
12531            }
12532            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12533        }
12534        Binder.restoreCallingIdentity(origId);
12535    }
12536
12537    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12538            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12539        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12540
12541        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12542                dumpPackage);
12543        boolean needSep = printedAnything;
12544
12545        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12546                dumpPackage, needSep, "  mFocusedActivity: ");
12547        if (printed) {
12548            printedAnything = true;
12549            needSep = false;
12550        }
12551
12552        if (dumpPackage == null) {
12553            if (needSep) {
12554                pw.println();
12555            }
12556            needSep = true;
12557            printedAnything = true;
12558            mStackSupervisor.dump(pw, "  ");
12559        }
12560
12561        if (!printedAnything) {
12562            pw.println("  (nothing)");
12563        }
12564    }
12565
12566    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12567            int opti, boolean dumpAll, String dumpPackage) {
12568        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12569
12570        boolean printedAnything = false;
12571
12572        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12573            boolean printedHeader = false;
12574
12575            final int N = mRecentTasks.size();
12576            for (int i=0; i<N; i++) {
12577                TaskRecord tr = mRecentTasks.get(i);
12578                if (dumpPackage != null) {
12579                    if (tr.realActivity == null ||
12580                            !dumpPackage.equals(tr.realActivity)) {
12581                        continue;
12582                    }
12583                }
12584                if (!printedHeader) {
12585                    pw.println("  Recent tasks:");
12586                    printedHeader = true;
12587                    printedAnything = true;
12588                }
12589                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12590                        pw.println(tr);
12591                if (dumpAll) {
12592                    mRecentTasks.get(i).dump(pw, "    ");
12593                }
12594            }
12595        }
12596
12597        if (!printedAnything) {
12598            pw.println("  (nothing)");
12599        }
12600    }
12601
12602    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12603            int opti, boolean dumpAll, String dumpPackage) {
12604        boolean needSep = false;
12605        boolean printedAnything = false;
12606        int numPers = 0;
12607
12608        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12609
12610        if (dumpAll) {
12611            final int NP = mProcessNames.getMap().size();
12612            for (int ip=0; ip<NP; ip++) {
12613                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12614                final int NA = procs.size();
12615                for (int ia=0; ia<NA; ia++) {
12616                    ProcessRecord r = procs.valueAt(ia);
12617                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12618                        continue;
12619                    }
12620                    if (!needSep) {
12621                        pw.println("  All known processes:");
12622                        needSep = true;
12623                        printedAnything = true;
12624                    }
12625                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12626                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12627                        pw.print(" "); pw.println(r);
12628                    r.dump(pw, "    ");
12629                    if (r.persistent) {
12630                        numPers++;
12631                    }
12632                }
12633            }
12634        }
12635
12636        if (mIsolatedProcesses.size() > 0) {
12637            boolean printed = false;
12638            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12639                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12640                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12641                    continue;
12642                }
12643                if (!printed) {
12644                    if (needSep) {
12645                        pw.println();
12646                    }
12647                    pw.println("  Isolated process list (sorted by uid):");
12648                    printedAnything = true;
12649                    printed = true;
12650                    needSep = true;
12651                }
12652                pw.println(String.format("%sIsolated #%2d: %s",
12653                        "    ", i, r.toString()));
12654            }
12655        }
12656
12657        if (mLruProcesses.size() > 0) {
12658            if (needSep) {
12659                pw.println();
12660            }
12661            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12662                    pw.print(" total, non-act at ");
12663                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12664                    pw.print(", non-svc at ");
12665                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12666                    pw.println("):");
12667            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12668            needSep = true;
12669            printedAnything = true;
12670        }
12671
12672        if (dumpAll || dumpPackage != null) {
12673            synchronized (mPidsSelfLocked) {
12674                boolean printed = false;
12675                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12676                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12677                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12678                        continue;
12679                    }
12680                    if (!printed) {
12681                        if (needSep) pw.println();
12682                        needSep = true;
12683                        pw.println("  PID mappings:");
12684                        printed = true;
12685                        printedAnything = true;
12686                    }
12687                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12688                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12689                }
12690            }
12691        }
12692
12693        if (mForegroundProcesses.size() > 0) {
12694            synchronized (mPidsSelfLocked) {
12695                boolean printed = false;
12696                for (int i=0; i<mForegroundProcesses.size(); i++) {
12697                    ProcessRecord r = mPidsSelfLocked.get(
12698                            mForegroundProcesses.valueAt(i).pid);
12699                    if (dumpPackage != null && (r == null
12700                            || !r.pkgList.containsKey(dumpPackage))) {
12701                        continue;
12702                    }
12703                    if (!printed) {
12704                        if (needSep) pw.println();
12705                        needSep = true;
12706                        pw.println("  Foreground Processes:");
12707                        printed = true;
12708                        printedAnything = true;
12709                    }
12710                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12711                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12712                }
12713            }
12714        }
12715
12716        if (mPersistentStartingProcesses.size() > 0) {
12717            if (needSep) pw.println();
12718            needSep = true;
12719            printedAnything = true;
12720            pw.println("  Persisent processes that are starting:");
12721            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12722                    "Starting Norm", "Restarting PERS", dumpPackage);
12723        }
12724
12725        if (mRemovedProcesses.size() > 0) {
12726            if (needSep) pw.println();
12727            needSep = true;
12728            printedAnything = true;
12729            pw.println("  Processes that are being removed:");
12730            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12731                    "Removed Norm", "Removed PERS", dumpPackage);
12732        }
12733
12734        if (mProcessesOnHold.size() > 0) {
12735            if (needSep) pw.println();
12736            needSep = true;
12737            printedAnything = true;
12738            pw.println("  Processes that are on old until the system is ready:");
12739            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12740                    "OnHold Norm", "OnHold PERS", dumpPackage);
12741        }
12742
12743        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12744
12745        if (mProcessCrashTimes.getMap().size() > 0) {
12746            boolean printed = false;
12747            long now = SystemClock.uptimeMillis();
12748            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12749            final int NP = pmap.size();
12750            for (int ip=0; ip<NP; ip++) {
12751                String pname = pmap.keyAt(ip);
12752                SparseArray<Long> uids = pmap.valueAt(ip);
12753                final int N = uids.size();
12754                for (int i=0; i<N; i++) {
12755                    int puid = uids.keyAt(i);
12756                    ProcessRecord r = mProcessNames.get(pname, puid);
12757                    if (dumpPackage != null && (r == null
12758                            || !r.pkgList.containsKey(dumpPackage))) {
12759                        continue;
12760                    }
12761                    if (!printed) {
12762                        if (needSep) pw.println();
12763                        needSep = true;
12764                        pw.println("  Time since processes crashed:");
12765                        printed = true;
12766                        printedAnything = true;
12767                    }
12768                    pw.print("    Process "); pw.print(pname);
12769                            pw.print(" uid "); pw.print(puid);
12770                            pw.print(": last crashed ");
12771                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12772                            pw.println(" ago");
12773                }
12774            }
12775        }
12776
12777        if (mBadProcesses.getMap().size() > 0) {
12778            boolean printed = false;
12779            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12780            final int NP = pmap.size();
12781            for (int ip=0; ip<NP; ip++) {
12782                String pname = pmap.keyAt(ip);
12783                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12784                final int N = uids.size();
12785                for (int i=0; i<N; i++) {
12786                    int puid = uids.keyAt(i);
12787                    ProcessRecord r = mProcessNames.get(pname, puid);
12788                    if (dumpPackage != null && (r == null
12789                            || !r.pkgList.containsKey(dumpPackage))) {
12790                        continue;
12791                    }
12792                    if (!printed) {
12793                        if (needSep) pw.println();
12794                        needSep = true;
12795                        pw.println("  Bad processes:");
12796                        printedAnything = true;
12797                    }
12798                    BadProcessInfo info = uids.valueAt(i);
12799                    pw.print("    Bad process "); pw.print(pname);
12800                            pw.print(" uid "); pw.print(puid);
12801                            pw.print(": crashed at time "); pw.println(info.time);
12802                    if (info.shortMsg != null) {
12803                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12804                    }
12805                    if (info.longMsg != null) {
12806                        pw.print("      Long msg: "); pw.println(info.longMsg);
12807                    }
12808                    if (info.stack != null) {
12809                        pw.println("      Stack:");
12810                        int lastPos = 0;
12811                        for (int pos=0; pos<info.stack.length(); pos++) {
12812                            if (info.stack.charAt(pos) == '\n') {
12813                                pw.print("        ");
12814                                pw.write(info.stack, lastPos, pos-lastPos);
12815                                pw.println();
12816                                lastPos = pos+1;
12817                            }
12818                        }
12819                        if (lastPos < info.stack.length()) {
12820                            pw.print("        ");
12821                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12822                            pw.println();
12823                        }
12824                    }
12825                }
12826            }
12827        }
12828
12829        if (dumpPackage == null) {
12830            pw.println();
12831            needSep = false;
12832            pw.println("  mStartedUsers:");
12833            for (int i=0; i<mStartedUsers.size(); i++) {
12834                UserStartedState uss = mStartedUsers.valueAt(i);
12835                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12836                        pw.print(": "); uss.dump("", pw);
12837            }
12838            pw.print("  mStartedUserArray: [");
12839            for (int i=0; i<mStartedUserArray.length; i++) {
12840                if (i > 0) pw.print(", ");
12841                pw.print(mStartedUserArray[i]);
12842            }
12843            pw.println("]");
12844            pw.print("  mUserLru: [");
12845            for (int i=0; i<mUserLru.size(); i++) {
12846                if (i > 0) pw.print(", ");
12847                pw.print(mUserLru.get(i));
12848            }
12849            pw.println("]");
12850            if (dumpAll) {
12851                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12852            }
12853            synchronized (mUserProfileGroupIdsSelfLocked) {
12854                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12855                    pw.println("  mUserProfileGroupIds:");
12856                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12857                        pw.print("    User #");
12858                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12859                        pw.print(" -> profile #");
12860                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12861                    }
12862                }
12863            }
12864        }
12865        if (mHomeProcess != null && (dumpPackage == null
12866                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12867            if (needSep) {
12868                pw.println();
12869                needSep = false;
12870            }
12871            pw.println("  mHomeProcess: " + mHomeProcess);
12872        }
12873        if (mPreviousProcess != null && (dumpPackage == null
12874                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12875            if (needSep) {
12876                pw.println();
12877                needSep = false;
12878            }
12879            pw.println("  mPreviousProcess: " + mPreviousProcess);
12880        }
12881        if (dumpAll) {
12882            StringBuilder sb = new StringBuilder(128);
12883            sb.append("  mPreviousProcessVisibleTime: ");
12884            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12885            pw.println(sb);
12886        }
12887        if (mHeavyWeightProcess != null && (dumpPackage == null
12888                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12889            if (needSep) {
12890                pw.println();
12891                needSep = false;
12892            }
12893            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12894        }
12895        if (dumpPackage == null) {
12896            pw.println("  mConfiguration: " + mConfiguration);
12897        }
12898        if (dumpAll) {
12899            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12900            if (mCompatModePackages.getPackages().size() > 0) {
12901                boolean printed = false;
12902                for (Map.Entry<String, Integer> entry
12903                        : mCompatModePackages.getPackages().entrySet()) {
12904                    String pkg = entry.getKey();
12905                    int mode = entry.getValue();
12906                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12907                        continue;
12908                    }
12909                    if (!printed) {
12910                        pw.println("  mScreenCompatPackages:");
12911                        printed = true;
12912                    }
12913                    pw.print("    "); pw.print(pkg); pw.print(": ");
12914                            pw.print(mode); pw.println();
12915                }
12916            }
12917        }
12918        if (dumpPackage == null) {
12919            pw.println("  mWakefulness="
12920                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12921            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12922                    + lockScreenShownToString());
12923            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12924                    + " mTestPssMode=" + mTestPssMode);
12925        }
12926        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12927                || mOrigWaitForDebugger) {
12928            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12929                    || dumpPackage.equals(mOrigDebugApp)) {
12930                if (needSep) {
12931                    pw.println();
12932                    needSep = false;
12933                }
12934                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12935                        + " mDebugTransient=" + mDebugTransient
12936                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12937            }
12938        }
12939        if (mOpenGlTraceApp != null) {
12940            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12941                if (needSep) {
12942                    pw.println();
12943                    needSep = false;
12944                }
12945                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12946            }
12947        }
12948        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12949                || mProfileFd != null) {
12950            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12951                if (needSep) {
12952                    pw.println();
12953                    needSep = false;
12954                }
12955                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12956                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12957                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12958                        + mAutoStopProfiler);
12959                pw.println("  mProfileType=" + mProfileType);
12960            }
12961        }
12962        if (dumpPackage == null) {
12963            if (mAlwaysFinishActivities || mController != null) {
12964                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12965                        + " mController=" + mController);
12966            }
12967            if (dumpAll) {
12968                pw.println("  Total persistent processes: " + numPers);
12969                pw.println("  mProcessesReady=" + mProcessesReady
12970                        + " mSystemReady=" + mSystemReady
12971                        + " mBooted=" + mBooted
12972                        + " mFactoryTest=" + mFactoryTest);
12973                pw.println("  mBooting=" + mBooting
12974                        + " mCallFinishBooting=" + mCallFinishBooting
12975                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12976                pw.print("  mLastPowerCheckRealtime=");
12977                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12978                        pw.println("");
12979                pw.print("  mLastPowerCheckUptime=");
12980                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12981                        pw.println("");
12982                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12983                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12984                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12985                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12986                        + " (" + mLruProcesses.size() + " total)"
12987                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12988                        + " mNumServiceProcs=" + mNumServiceProcs
12989                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12990                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12991                        + " mLastMemoryLevel" + mLastMemoryLevel
12992                        + " mLastNumProcesses" + mLastNumProcesses);
12993                long now = SystemClock.uptimeMillis();
12994                pw.print("  mLastIdleTime=");
12995                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12996                        pw.print(" mLowRamSinceLastIdle=");
12997                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12998                        pw.println();
12999            }
13000        }
13001
13002        if (!printedAnything) {
13003            pw.println("  (nothing)");
13004        }
13005    }
13006
13007    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13008            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13009        if (mProcessesToGc.size() > 0) {
13010            boolean printed = false;
13011            long now = SystemClock.uptimeMillis();
13012            for (int i=0; i<mProcessesToGc.size(); i++) {
13013                ProcessRecord proc = mProcessesToGc.get(i);
13014                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13015                    continue;
13016                }
13017                if (!printed) {
13018                    if (needSep) pw.println();
13019                    needSep = true;
13020                    pw.println("  Processes that are waiting to GC:");
13021                    printed = true;
13022                }
13023                pw.print("    Process "); pw.println(proc);
13024                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13025                        pw.print(", last gced=");
13026                        pw.print(now-proc.lastRequestedGc);
13027                        pw.print(" ms ago, last lowMem=");
13028                        pw.print(now-proc.lastLowMemory);
13029                        pw.println(" ms ago");
13030
13031            }
13032        }
13033        return needSep;
13034    }
13035
13036    void printOomLevel(PrintWriter pw, String name, int adj) {
13037        pw.print("    ");
13038        if (adj >= 0) {
13039            pw.print(' ');
13040            if (adj < 10) pw.print(' ');
13041        } else {
13042            if (adj > -10) pw.print(' ');
13043        }
13044        pw.print(adj);
13045        pw.print(": ");
13046        pw.print(name);
13047        pw.print(" (");
13048        pw.print(mProcessList.getMemLevel(adj)/1024);
13049        pw.println(" kB)");
13050    }
13051
13052    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13053            int opti, boolean dumpAll) {
13054        boolean needSep = false;
13055
13056        if (mLruProcesses.size() > 0) {
13057            if (needSep) pw.println();
13058            needSep = true;
13059            pw.println("  OOM levels:");
13060            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13061            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13062            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13063            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13064            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13065            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13066            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13067            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13068            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13069            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13070            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13071            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13072            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13073            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13074
13075            if (needSep) pw.println();
13076            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13077                    pw.print(" total, non-act at ");
13078                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13079                    pw.print(", non-svc at ");
13080                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13081                    pw.println("):");
13082            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13083            needSep = true;
13084        }
13085
13086        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13087
13088        pw.println();
13089        pw.println("  mHomeProcess: " + mHomeProcess);
13090        pw.println("  mPreviousProcess: " + mPreviousProcess);
13091        if (mHeavyWeightProcess != null) {
13092            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13093        }
13094
13095        return true;
13096    }
13097
13098    /**
13099     * There are three ways to call this:
13100     *  - no provider specified: dump all the providers
13101     *  - a flattened component name that matched an existing provider was specified as the
13102     *    first arg: dump that one provider
13103     *  - the first arg isn't the flattened component name of an existing provider:
13104     *    dump all providers whose component contains the first arg as a substring
13105     */
13106    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13107            int opti, boolean dumpAll) {
13108        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13109    }
13110
13111    static class ItemMatcher {
13112        ArrayList<ComponentName> components;
13113        ArrayList<String> strings;
13114        ArrayList<Integer> objects;
13115        boolean all;
13116
13117        ItemMatcher() {
13118            all = true;
13119        }
13120
13121        void build(String name) {
13122            ComponentName componentName = ComponentName.unflattenFromString(name);
13123            if (componentName != null) {
13124                if (components == null) {
13125                    components = new ArrayList<ComponentName>();
13126                }
13127                components.add(componentName);
13128                all = false;
13129            } else {
13130                int objectId = 0;
13131                // Not a '/' separated full component name; maybe an object ID?
13132                try {
13133                    objectId = Integer.parseInt(name, 16);
13134                    if (objects == null) {
13135                        objects = new ArrayList<Integer>();
13136                    }
13137                    objects.add(objectId);
13138                    all = false;
13139                } catch (RuntimeException e) {
13140                    // Not an integer; just do string match.
13141                    if (strings == null) {
13142                        strings = new ArrayList<String>();
13143                    }
13144                    strings.add(name);
13145                    all = false;
13146                }
13147            }
13148        }
13149
13150        int build(String[] args, int opti) {
13151            for (; opti<args.length; opti++) {
13152                String name = args[opti];
13153                if ("--".equals(name)) {
13154                    return opti+1;
13155                }
13156                build(name);
13157            }
13158            return opti;
13159        }
13160
13161        boolean match(Object object, ComponentName comp) {
13162            if (all) {
13163                return true;
13164            }
13165            if (components != null) {
13166                for (int i=0; i<components.size(); i++) {
13167                    if (components.get(i).equals(comp)) {
13168                        return true;
13169                    }
13170                }
13171            }
13172            if (objects != null) {
13173                for (int i=0; i<objects.size(); i++) {
13174                    if (System.identityHashCode(object) == objects.get(i)) {
13175                        return true;
13176                    }
13177                }
13178            }
13179            if (strings != null) {
13180                String flat = comp.flattenToString();
13181                for (int i=0; i<strings.size(); i++) {
13182                    if (flat.contains(strings.get(i))) {
13183                        return true;
13184                    }
13185                }
13186            }
13187            return false;
13188        }
13189    }
13190
13191    /**
13192     * There are three things that cmd can be:
13193     *  - a flattened component name that matches an existing activity
13194     *  - the cmd arg isn't the flattened component name of an existing activity:
13195     *    dump all activity whose component contains the cmd as a substring
13196     *  - A hex number of the ActivityRecord object instance.
13197     */
13198    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13199            int opti, boolean dumpAll) {
13200        ArrayList<ActivityRecord> activities;
13201
13202        synchronized (this) {
13203            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13204        }
13205
13206        if (activities.size() <= 0) {
13207            return false;
13208        }
13209
13210        String[] newArgs = new String[args.length - opti];
13211        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13212
13213        TaskRecord lastTask = null;
13214        boolean needSep = false;
13215        for (int i=activities.size()-1; i>=0; i--) {
13216            ActivityRecord r = activities.get(i);
13217            if (needSep) {
13218                pw.println();
13219            }
13220            needSep = true;
13221            synchronized (this) {
13222                if (lastTask != r.task) {
13223                    lastTask = r.task;
13224                    pw.print("TASK "); pw.print(lastTask.affinity);
13225                            pw.print(" id="); pw.println(lastTask.taskId);
13226                    if (dumpAll) {
13227                        lastTask.dump(pw, "  ");
13228                    }
13229                }
13230            }
13231            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13232        }
13233        return true;
13234    }
13235
13236    /**
13237     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13238     * there is a thread associated with the activity.
13239     */
13240    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13241            final ActivityRecord r, String[] args, boolean dumpAll) {
13242        String innerPrefix = prefix + "  ";
13243        synchronized (this) {
13244            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13245                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13246                    pw.print(" pid=");
13247                    if (r.app != null) pw.println(r.app.pid);
13248                    else pw.println("(not running)");
13249            if (dumpAll) {
13250                r.dump(pw, innerPrefix);
13251            }
13252        }
13253        if (r.app != null && r.app.thread != null) {
13254            // flush anything that is already in the PrintWriter since the thread is going
13255            // to write to the file descriptor directly
13256            pw.flush();
13257            try {
13258                TransferPipe tp = new TransferPipe();
13259                try {
13260                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13261                            r.appToken, innerPrefix, args);
13262                    tp.go(fd);
13263                } finally {
13264                    tp.kill();
13265                }
13266            } catch (IOException e) {
13267                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13268            } catch (RemoteException e) {
13269                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13270            }
13271        }
13272    }
13273
13274    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13275            int opti, boolean dumpAll, String dumpPackage) {
13276        boolean needSep = false;
13277        boolean onlyHistory = false;
13278        boolean printedAnything = false;
13279
13280        if ("history".equals(dumpPackage)) {
13281            if (opti < args.length && "-s".equals(args[opti])) {
13282                dumpAll = false;
13283            }
13284            onlyHistory = true;
13285            dumpPackage = null;
13286        }
13287
13288        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13289        if (!onlyHistory && dumpAll) {
13290            if (mRegisteredReceivers.size() > 0) {
13291                boolean printed = false;
13292                Iterator it = mRegisteredReceivers.values().iterator();
13293                while (it.hasNext()) {
13294                    ReceiverList r = (ReceiverList)it.next();
13295                    if (dumpPackage != null && (r.app == null ||
13296                            !dumpPackage.equals(r.app.info.packageName))) {
13297                        continue;
13298                    }
13299                    if (!printed) {
13300                        pw.println("  Registered Receivers:");
13301                        needSep = true;
13302                        printed = true;
13303                        printedAnything = true;
13304                    }
13305                    pw.print("  * "); pw.println(r);
13306                    r.dump(pw, "    ");
13307                }
13308            }
13309
13310            if (mReceiverResolver.dump(pw, needSep ?
13311                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13312                    "    ", dumpPackage, false, false)) {
13313                needSep = true;
13314                printedAnything = true;
13315            }
13316        }
13317
13318        for (BroadcastQueue q : mBroadcastQueues) {
13319            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13320            printedAnything |= needSep;
13321        }
13322
13323        needSep = true;
13324
13325        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13326            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13327                if (needSep) {
13328                    pw.println();
13329                }
13330                needSep = true;
13331                printedAnything = true;
13332                pw.print("  Sticky broadcasts for user ");
13333                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13334                StringBuilder sb = new StringBuilder(128);
13335                for (Map.Entry<String, ArrayList<Intent>> ent
13336                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13337                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13338                    if (dumpAll) {
13339                        pw.println(":");
13340                        ArrayList<Intent> intents = ent.getValue();
13341                        final int N = intents.size();
13342                        for (int i=0; i<N; i++) {
13343                            sb.setLength(0);
13344                            sb.append("    Intent: ");
13345                            intents.get(i).toShortString(sb, false, true, false, false);
13346                            pw.println(sb.toString());
13347                            Bundle bundle = intents.get(i).getExtras();
13348                            if (bundle != null) {
13349                                pw.print("      ");
13350                                pw.println(bundle.toString());
13351                            }
13352                        }
13353                    } else {
13354                        pw.println("");
13355                    }
13356                }
13357            }
13358        }
13359
13360        if (!onlyHistory && dumpAll) {
13361            pw.println();
13362            for (BroadcastQueue queue : mBroadcastQueues) {
13363                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13364                        + queue.mBroadcastsScheduled);
13365            }
13366            pw.println("  mHandler:");
13367            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13368            needSep = true;
13369            printedAnything = true;
13370        }
13371
13372        if (!printedAnything) {
13373            pw.println("  (nothing)");
13374        }
13375    }
13376
13377    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13378            int opti, boolean dumpAll, String dumpPackage) {
13379        boolean needSep;
13380        boolean printedAnything = false;
13381
13382        ItemMatcher matcher = new ItemMatcher();
13383        matcher.build(args, opti);
13384
13385        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13386
13387        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13388        printedAnything |= needSep;
13389
13390        if (mLaunchingProviders.size() > 0) {
13391            boolean printed = false;
13392            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13393                ContentProviderRecord r = mLaunchingProviders.get(i);
13394                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13395                    continue;
13396                }
13397                if (!printed) {
13398                    if (needSep) pw.println();
13399                    needSep = true;
13400                    pw.println("  Launching content providers:");
13401                    printed = true;
13402                    printedAnything = true;
13403                }
13404                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13405                        pw.println(r);
13406            }
13407        }
13408
13409        if (mGrantedUriPermissions.size() > 0) {
13410            boolean printed = false;
13411            int dumpUid = -2;
13412            if (dumpPackage != null) {
13413                try {
13414                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13415                } catch (NameNotFoundException e) {
13416                    dumpUid = -1;
13417                }
13418            }
13419            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13420                int uid = mGrantedUriPermissions.keyAt(i);
13421                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13422                    continue;
13423                }
13424                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13425                if (!printed) {
13426                    if (needSep) pw.println();
13427                    needSep = true;
13428                    pw.println("  Granted Uri Permissions:");
13429                    printed = true;
13430                    printedAnything = true;
13431                }
13432                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13433                for (UriPermission perm : perms.values()) {
13434                    pw.print("    "); pw.println(perm);
13435                    if (dumpAll) {
13436                        perm.dump(pw, "      ");
13437                    }
13438                }
13439            }
13440        }
13441
13442        if (!printedAnything) {
13443            pw.println("  (nothing)");
13444        }
13445    }
13446
13447    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13448            int opti, boolean dumpAll, String dumpPackage) {
13449        boolean printed = false;
13450
13451        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13452
13453        if (mIntentSenderRecords.size() > 0) {
13454            Iterator<WeakReference<PendingIntentRecord>> it
13455                    = mIntentSenderRecords.values().iterator();
13456            while (it.hasNext()) {
13457                WeakReference<PendingIntentRecord> ref = it.next();
13458                PendingIntentRecord rec = ref != null ? ref.get(): null;
13459                if (dumpPackage != null && (rec == null
13460                        || !dumpPackage.equals(rec.key.packageName))) {
13461                    continue;
13462                }
13463                printed = true;
13464                if (rec != null) {
13465                    pw.print("  * "); pw.println(rec);
13466                    if (dumpAll) {
13467                        rec.dump(pw, "    ");
13468                    }
13469                } else {
13470                    pw.print("  * "); pw.println(ref);
13471                }
13472            }
13473        }
13474
13475        if (!printed) {
13476            pw.println("  (nothing)");
13477        }
13478    }
13479
13480    private static final int dumpProcessList(PrintWriter pw,
13481            ActivityManagerService service, List list,
13482            String prefix, String normalLabel, String persistentLabel,
13483            String dumpPackage) {
13484        int numPers = 0;
13485        final int N = list.size()-1;
13486        for (int i=N; i>=0; i--) {
13487            ProcessRecord r = (ProcessRecord)list.get(i);
13488            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13489                continue;
13490            }
13491            pw.println(String.format("%s%s #%2d: %s",
13492                    prefix, (r.persistent ? persistentLabel : normalLabel),
13493                    i, r.toString()));
13494            if (r.persistent) {
13495                numPers++;
13496            }
13497        }
13498        return numPers;
13499    }
13500
13501    private static final boolean dumpProcessOomList(PrintWriter pw,
13502            ActivityManagerService service, List<ProcessRecord> origList,
13503            String prefix, String normalLabel, String persistentLabel,
13504            boolean inclDetails, String dumpPackage) {
13505
13506        ArrayList<Pair<ProcessRecord, Integer>> list
13507                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13508        for (int i=0; i<origList.size(); i++) {
13509            ProcessRecord r = origList.get(i);
13510            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13511                continue;
13512            }
13513            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13514        }
13515
13516        if (list.size() <= 0) {
13517            return false;
13518        }
13519
13520        Comparator<Pair<ProcessRecord, Integer>> comparator
13521                = new Comparator<Pair<ProcessRecord, Integer>>() {
13522            @Override
13523            public int compare(Pair<ProcessRecord, Integer> object1,
13524                    Pair<ProcessRecord, Integer> object2) {
13525                if (object1.first.setAdj != object2.first.setAdj) {
13526                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13527                }
13528                if (object1.second.intValue() != object2.second.intValue()) {
13529                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13530                }
13531                return 0;
13532            }
13533        };
13534
13535        Collections.sort(list, comparator);
13536
13537        final long curRealtime = SystemClock.elapsedRealtime();
13538        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13539        final long curUptime = SystemClock.uptimeMillis();
13540        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13541
13542        for (int i=list.size()-1; i>=0; i--) {
13543            ProcessRecord r = list.get(i).first;
13544            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13545            char schedGroup;
13546            switch (r.setSchedGroup) {
13547                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13548                    schedGroup = 'B';
13549                    break;
13550                case Process.THREAD_GROUP_DEFAULT:
13551                    schedGroup = 'F';
13552                    break;
13553                default:
13554                    schedGroup = '?';
13555                    break;
13556            }
13557            char foreground;
13558            if (r.foregroundActivities) {
13559                foreground = 'A';
13560            } else if (r.foregroundServices) {
13561                foreground = 'S';
13562            } else {
13563                foreground = ' ';
13564            }
13565            String procState = ProcessList.makeProcStateString(r.curProcState);
13566            pw.print(prefix);
13567            pw.print(r.persistent ? persistentLabel : normalLabel);
13568            pw.print(" #");
13569            int num = (origList.size()-1)-list.get(i).second;
13570            if (num < 10) pw.print(' ');
13571            pw.print(num);
13572            pw.print(": ");
13573            pw.print(oomAdj);
13574            pw.print(' ');
13575            pw.print(schedGroup);
13576            pw.print('/');
13577            pw.print(foreground);
13578            pw.print('/');
13579            pw.print(procState);
13580            pw.print(" trm:");
13581            if (r.trimMemoryLevel < 10) pw.print(' ');
13582            pw.print(r.trimMemoryLevel);
13583            pw.print(' ');
13584            pw.print(r.toShortString());
13585            pw.print(" (");
13586            pw.print(r.adjType);
13587            pw.println(')');
13588            if (r.adjSource != null || r.adjTarget != null) {
13589                pw.print(prefix);
13590                pw.print("    ");
13591                if (r.adjTarget instanceof ComponentName) {
13592                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13593                } else if (r.adjTarget != null) {
13594                    pw.print(r.adjTarget.toString());
13595                } else {
13596                    pw.print("{null}");
13597                }
13598                pw.print("<=");
13599                if (r.adjSource instanceof ProcessRecord) {
13600                    pw.print("Proc{");
13601                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13602                    pw.println("}");
13603                } else if (r.adjSource != null) {
13604                    pw.println(r.adjSource.toString());
13605                } else {
13606                    pw.println("{null}");
13607                }
13608            }
13609            if (inclDetails) {
13610                pw.print(prefix);
13611                pw.print("    ");
13612                pw.print("oom: max="); pw.print(r.maxAdj);
13613                pw.print(" curRaw="); pw.print(r.curRawAdj);
13614                pw.print(" setRaw="); pw.print(r.setRawAdj);
13615                pw.print(" cur="); pw.print(r.curAdj);
13616                pw.print(" set="); pw.println(r.setAdj);
13617                pw.print(prefix);
13618                pw.print("    ");
13619                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13620                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13621                pw.print(" lastPss="); pw.print(r.lastPss);
13622                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13623                pw.print(prefix);
13624                pw.print("    ");
13625                pw.print("cached="); pw.print(r.cached);
13626                pw.print(" empty="); pw.print(r.empty);
13627                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13628
13629                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13630                    if (r.lastWakeTime != 0) {
13631                        long wtime;
13632                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13633                        synchronized (stats) {
13634                            wtime = stats.getProcessWakeTime(r.info.uid,
13635                                    r.pid, curRealtime);
13636                        }
13637                        long timeUsed = wtime - r.lastWakeTime;
13638                        pw.print(prefix);
13639                        pw.print("    ");
13640                        pw.print("keep awake over ");
13641                        TimeUtils.formatDuration(realtimeSince, pw);
13642                        pw.print(" used ");
13643                        TimeUtils.formatDuration(timeUsed, pw);
13644                        pw.print(" (");
13645                        pw.print((timeUsed*100)/realtimeSince);
13646                        pw.println("%)");
13647                    }
13648                    if (r.lastCpuTime != 0) {
13649                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13650                        pw.print(prefix);
13651                        pw.print("    ");
13652                        pw.print("run cpu over ");
13653                        TimeUtils.formatDuration(uptimeSince, pw);
13654                        pw.print(" used ");
13655                        TimeUtils.formatDuration(timeUsed, pw);
13656                        pw.print(" (");
13657                        pw.print((timeUsed*100)/uptimeSince);
13658                        pw.println("%)");
13659                    }
13660                }
13661            }
13662        }
13663        return true;
13664    }
13665
13666    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13667            String[] args) {
13668        ArrayList<ProcessRecord> procs;
13669        synchronized (this) {
13670            if (args != null && args.length > start
13671                    && args[start].charAt(0) != '-') {
13672                procs = new ArrayList<ProcessRecord>();
13673                int pid = -1;
13674                try {
13675                    pid = Integer.parseInt(args[start]);
13676                } catch (NumberFormatException e) {
13677                }
13678                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13679                    ProcessRecord proc = mLruProcesses.get(i);
13680                    if (proc.pid == pid) {
13681                        procs.add(proc);
13682                    } else if (allPkgs && proc.pkgList != null
13683                            && proc.pkgList.containsKey(args[start])) {
13684                        procs.add(proc);
13685                    } else if (proc.processName.equals(args[start])) {
13686                        procs.add(proc);
13687                    }
13688                }
13689                if (procs.size() <= 0) {
13690                    return null;
13691                }
13692            } else {
13693                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13694            }
13695        }
13696        return procs;
13697    }
13698
13699    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13700            PrintWriter pw, String[] args) {
13701        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13702        if (procs == null) {
13703            pw.println("No process found for: " + args[0]);
13704            return;
13705        }
13706
13707        long uptime = SystemClock.uptimeMillis();
13708        long realtime = SystemClock.elapsedRealtime();
13709        pw.println("Applications Graphics Acceleration Info:");
13710        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13711
13712        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13713            ProcessRecord r = procs.get(i);
13714            if (r.thread != null) {
13715                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13716                pw.flush();
13717                try {
13718                    TransferPipe tp = new TransferPipe();
13719                    try {
13720                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13721                        tp.go(fd);
13722                    } finally {
13723                        tp.kill();
13724                    }
13725                } catch (IOException e) {
13726                    pw.println("Failure while dumping the app: " + r);
13727                    pw.flush();
13728                } catch (RemoteException e) {
13729                    pw.println("Got a RemoteException while dumping the app " + r);
13730                    pw.flush();
13731                }
13732            }
13733        }
13734    }
13735
13736    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13737        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13738        if (procs == null) {
13739            pw.println("No process found for: " + args[0]);
13740            return;
13741        }
13742
13743        pw.println("Applications Database Info:");
13744
13745        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13746            ProcessRecord r = procs.get(i);
13747            if (r.thread != null) {
13748                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13749                pw.flush();
13750                try {
13751                    TransferPipe tp = new TransferPipe();
13752                    try {
13753                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13754                        tp.go(fd);
13755                    } finally {
13756                        tp.kill();
13757                    }
13758                } catch (IOException e) {
13759                    pw.println("Failure while dumping the app: " + r);
13760                    pw.flush();
13761                } catch (RemoteException e) {
13762                    pw.println("Got a RemoteException while dumping the app " + r);
13763                    pw.flush();
13764                }
13765            }
13766        }
13767    }
13768
13769    final static class MemItem {
13770        final boolean isProc;
13771        final String label;
13772        final String shortLabel;
13773        final long pss;
13774        final int id;
13775        final boolean hasActivities;
13776        ArrayList<MemItem> subitems;
13777
13778        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13779                boolean _hasActivities) {
13780            isProc = true;
13781            label = _label;
13782            shortLabel = _shortLabel;
13783            pss = _pss;
13784            id = _id;
13785            hasActivities = _hasActivities;
13786        }
13787
13788        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13789            isProc = false;
13790            label = _label;
13791            shortLabel = _shortLabel;
13792            pss = _pss;
13793            id = _id;
13794            hasActivities = false;
13795        }
13796    }
13797
13798    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13799            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13800        if (sort && !isCompact) {
13801            Collections.sort(items, new Comparator<MemItem>() {
13802                @Override
13803                public int compare(MemItem lhs, MemItem rhs) {
13804                    if (lhs.pss < rhs.pss) {
13805                        return 1;
13806                    } else if (lhs.pss > rhs.pss) {
13807                        return -1;
13808                    }
13809                    return 0;
13810                }
13811            });
13812        }
13813
13814        for (int i=0; i<items.size(); i++) {
13815            MemItem mi = items.get(i);
13816            if (!isCompact) {
13817                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13818            } else if (mi.isProc) {
13819                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13820                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13821                pw.println(mi.hasActivities ? ",a" : ",e");
13822            } else {
13823                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13824                pw.println(mi.pss);
13825            }
13826            if (mi.subitems != null) {
13827                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13828                        true, isCompact);
13829            }
13830        }
13831    }
13832
13833    // These are in KB.
13834    static final long[] DUMP_MEM_BUCKETS = new long[] {
13835        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13836        120*1024, 160*1024, 200*1024,
13837        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13838        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13839    };
13840
13841    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13842            boolean stackLike) {
13843        int start = label.lastIndexOf('.');
13844        if (start >= 0) start++;
13845        else start = 0;
13846        int end = label.length();
13847        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13848            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13849                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13850                out.append(bucket);
13851                out.append(stackLike ? "MB." : "MB ");
13852                out.append(label, start, end);
13853                return;
13854            }
13855        }
13856        out.append(memKB/1024);
13857        out.append(stackLike ? "MB." : "MB ");
13858        out.append(label, start, end);
13859    }
13860
13861    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13862            ProcessList.NATIVE_ADJ,
13863            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13864            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13865            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13866            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13867            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13868            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13869    };
13870    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13871            "Native",
13872            "System", "Persistent", "Persistent Service", "Foreground",
13873            "Visible", "Perceptible",
13874            "Heavy Weight", "Backup",
13875            "A Services", "Home",
13876            "Previous", "B Services", "Cached"
13877    };
13878    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13879            "native",
13880            "sys", "pers", "persvc", "fore",
13881            "vis", "percept",
13882            "heavy", "backup",
13883            "servicea", "home",
13884            "prev", "serviceb", "cached"
13885    };
13886
13887    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13888            long realtime, boolean isCheckinRequest, boolean isCompact) {
13889        if (isCheckinRequest || isCompact) {
13890            // short checkin version
13891            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13892        } else {
13893            pw.println("Applications Memory Usage (kB):");
13894            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13895        }
13896    }
13897
13898    private static final int KSM_SHARED = 0;
13899    private static final int KSM_SHARING = 1;
13900    private static final int KSM_UNSHARED = 2;
13901    private static final int KSM_VOLATILE = 3;
13902
13903    private final long[] getKsmInfo() {
13904        long[] longOut = new long[4];
13905        final int[] SINGLE_LONG_FORMAT = new int[] {
13906            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13907        };
13908        long[] longTmp = new long[1];
13909        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13910                SINGLE_LONG_FORMAT, null, longTmp, null);
13911        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13912        longTmp[0] = 0;
13913        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13914                SINGLE_LONG_FORMAT, null, longTmp, null);
13915        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13916        longTmp[0] = 0;
13917        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13918                SINGLE_LONG_FORMAT, null, longTmp, null);
13919        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13920        longTmp[0] = 0;
13921        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13922                SINGLE_LONG_FORMAT, null, longTmp, null);
13923        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13924        return longOut;
13925    }
13926
13927    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13928            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13929        boolean dumpDetails = false;
13930        boolean dumpFullDetails = false;
13931        boolean dumpDalvik = false;
13932        boolean oomOnly = false;
13933        boolean isCompact = false;
13934        boolean localOnly = false;
13935        boolean packages = false;
13936
13937        int opti = 0;
13938        while (opti < args.length) {
13939            String opt = args[opti];
13940            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13941                break;
13942            }
13943            opti++;
13944            if ("-a".equals(opt)) {
13945                dumpDetails = true;
13946                dumpFullDetails = true;
13947                dumpDalvik = true;
13948            } else if ("-d".equals(opt)) {
13949                dumpDalvik = true;
13950            } else if ("-c".equals(opt)) {
13951                isCompact = true;
13952            } else if ("--oom".equals(opt)) {
13953                oomOnly = true;
13954            } else if ("--local".equals(opt)) {
13955                localOnly = true;
13956            } else if ("--package".equals(opt)) {
13957                packages = true;
13958            } else if ("-h".equals(opt)) {
13959                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13960                pw.println("  -a: include all available information for each process.");
13961                pw.println("  -d: include dalvik details when dumping process details.");
13962                pw.println("  -c: dump in a compact machine-parseable representation.");
13963                pw.println("  --oom: only show processes organized by oom adj.");
13964                pw.println("  --local: only collect details locally, don't call process.");
13965                pw.println("  --package: interpret process arg as package, dumping all");
13966                pw.println("             processes that have loaded that package.");
13967                pw.println("If [process] is specified it can be the name or ");
13968                pw.println("pid of a specific process to dump.");
13969                return;
13970            } else {
13971                pw.println("Unknown argument: " + opt + "; use -h for help");
13972            }
13973        }
13974
13975        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13976        long uptime = SystemClock.uptimeMillis();
13977        long realtime = SystemClock.elapsedRealtime();
13978        final long[] tmpLong = new long[1];
13979
13980        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13981        if (procs == null) {
13982            // No Java processes.  Maybe they want to print a native process.
13983            if (args != null && args.length > opti
13984                    && args[opti].charAt(0) != '-') {
13985                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13986                        = new ArrayList<ProcessCpuTracker.Stats>();
13987                updateCpuStatsNow();
13988                int findPid = -1;
13989                try {
13990                    findPid = Integer.parseInt(args[opti]);
13991                } catch (NumberFormatException e) {
13992                }
13993                synchronized (mProcessCpuTracker) {
13994                    final int N = mProcessCpuTracker.countStats();
13995                    for (int i=0; i<N; i++) {
13996                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13997                        if (st.pid == findPid || (st.baseName != null
13998                                && st.baseName.equals(args[opti]))) {
13999                            nativeProcs.add(st);
14000                        }
14001                    }
14002                }
14003                if (nativeProcs.size() > 0) {
14004                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14005                            isCompact);
14006                    Debug.MemoryInfo mi = null;
14007                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14008                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14009                        final int pid = r.pid;
14010                        if (!isCheckinRequest && dumpDetails) {
14011                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14012                        }
14013                        if (mi == null) {
14014                            mi = new Debug.MemoryInfo();
14015                        }
14016                        if (dumpDetails || (!brief && !oomOnly)) {
14017                            Debug.getMemoryInfo(pid, mi);
14018                        } else {
14019                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14020                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14021                        }
14022                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14023                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14024                        if (isCheckinRequest) {
14025                            pw.println();
14026                        }
14027                    }
14028                    return;
14029                }
14030            }
14031            pw.println("No process found for: " + args[opti]);
14032            return;
14033        }
14034
14035        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14036            dumpDetails = true;
14037        }
14038
14039        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14040
14041        String[] innerArgs = new String[args.length-opti];
14042        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14043
14044        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14045        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14046        long nativePss = 0;
14047        long dalvikPss = 0;
14048        long otherPss = 0;
14049        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14050
14051        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14052        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14053                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14054
14055        long totalPss = 0;
14056        long cachedPss = 0;
14057
14058        Debug.MemoryInfo mi = null;
14059        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14060            final ProcessRecord r = procs.get(i);
14061            final IApplicationThread thread;
14062            final int pid;
14063            final int oomAdj;
14064            final boolean hasActivities;
14065            synchronized (this) {
14066                thread = r.thread;
14067                pid = r.pid;
14068                oomAdj = r.getSetAdjWithServices();
14069                hasActivities = r.activities.size() > 0;
14070            }
14071            if (thread != null) {
14072                if (!isCheckinRequest && dumpDetails) {
14073                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14074                }
14075                if (mi == null) {
14076                    mi = new Debug.MemoryInfo();
14077                }
14078                if (dumpDetails || (!brief && !oomOnly)) {
14079                    Debug.getMemoryInfo(pid, mi);
14080                } else {
14081                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14082                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14083                }
14084                if (dumpDetails) {
14085                    if (localOnly) {
14086                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14087                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14088                        if (isCheckinRequest) {
14089                            pw.println();
14090                        }
14091                    } else {
14092                        try {
14093                            pw.flush();
14094                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14095                                    dumpDalvik, innerArgs);
14096                        } catch (RemoteException e) {
14097                            if (!isCheckinRequest) {
14098                                pw.println("Got RemoteException!");
14099                                pw.flush();
14100                            }
14101                        }
14102                    }
14103                }
14104
14105                final long myTotalPss = mi.getTotalPss();
14106                final long myTotalUss = mi.getTotalUss();
14107
14108                synchronized (this) {
14109                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14110                        // Record this for posterity if the process has been stable.
14111                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14112                    }
14113                }
14114
14115                if (!isCheckinRequest && mi != null) {
14116                    totalPss += myTotalPss;
14117                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14118                            (hasActivities ? " / activities)" : ")"),
14119                            r.processName, myTotalPss, pid, hasActivities);
14120                    procMems.add(pssItem);
14121                    procMemsMap.put(pid, pssItem);
14122
14123                    nativePss += mi.nativePss;
14124                    dalvikPss += mi.dalvikPss;
14125                    otherPss += mi.otherPss;
14126                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14127                        long mem = mi.getOtherPss(j);
14128                        miscPss[j] += mem;
14129                        otherPss -= mem;
14130                    }
14131
14132                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14133                        cachedPss += myTotalPss;
14134                    }
14135
14136                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14137                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14138                                || oomIndex == (oomPss.length-1)) {
14139                            oomPss[oomIndex] += myTotalPss;
14140                            if (oomProcs[oomIndex] == null) {
14141                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14142                            }
14143                            oomProcs[oomIndex].add(pssItem);
14144                            break;
14145                        }
14146                    }
14147                }
14148            }
14149        }
14150
14151        long nativeProcTotalPss = 0;
14152
14153        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14154            // If we are showing aggregations, also look for native processes to
14155            // include so that our aggregations are more accurate.
14156            updateCpuStatsNow();
14157            mi = null;
14158            synchronized (mProcessCpuTracker) {
14159                final int N = mProcessCpuTracker.countStats();
14160                for (int i=0; i<N; i++) {
14161                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14162                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14163                        if (mi == null) {
14164                            mi = new Debug.MemoryInfo();
14165                        }
14166                        if (!brief && !oomOnly) {
14167                            Debug.getMemoryInfo(st.pid, mi);
14168                        } else {
14169                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14170                            mi.nativePrivateDirty = (int)tmpLong[0];
14171                        }
14172
14173                        final long myTotalPss = mi.getTotalPss();
14174                        totalPss += myTotalPss;
14175                        nativeProcTotalPss += myTotalPss;
14176
14177                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14178                                st.name, myTotalPss, st.pid, false);
14179                        procMems.add(pssItem);
14180
14181                        nativePss += mi.nativePss;
14182                        dalvikPss += mi.dalvikPss;
14183                        otherPss += mi.otherPss;
14184                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14185                            long mem = mi.getOtherPss(j);
14186                            miscPss[j] += mem;
14187                            otherPss -= mem;
14188                        }
14189                        oomPss[0] += myTotalPss;
14190                        if (oomProcs[0] == null) {
14191                            oomProcs[0] = new ArrayList<MemItem>();
14192                        }
14193                        oomProcs[0].add(pssItem);
14194                    }
14195                }
14196            }
14197
14198            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14199
14200            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14201            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14202            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14203            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14204                String label = Debug.MemoryInfo.getOtherLabel(j);
14205                catMems.add(new MemItem(label, label, miscPss[j], j));
14206            }
14207
14208            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14209            for (int j=0; j<oomPss.length; j++) {
14210                if (oomPss[j] != 0) {
14211                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14212                            : DUMP_MEM_OOM_LABEL[j];
14213                    MemItem item = new MemItem(label, label, oomPss[j],
14214                            DUMP_MEM_OOM_ADJ[j]);
14215                    item.subitems = oomProcs[j];
14216                    oomMems.add(item);
14217                }
14218            }
14219
14220            if (!brief && !oomOnly && !isCompact) {
14221                pw.println();
14222                pw.println("Total PSS by process:");
14223                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14224                pw.println();
14225            }
14226            if (!isCompact) {
14227                pw.println("Total PSS by OOM adjustment:");
14228            }
14229            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14230            if (!brief && !oomOnly) {
14231                PrintWriter out = categoryPw != null ? categoryPw : pw;
14232                if (!isCompact) {
14233                    out.println();
14234                    out.println("Total PSS by category:");
14235                }
14236                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14237            }
14238            if (!isCompact) {
14239                pw.println();
14240            }
14241            MemInfoReader memInfo = new MemInfoReader();
14242            memInfo.readMemInfo();
14243            if (nativeProcTotalPss > 0) {
14244                synchronized (this) {
14245                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14246                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14247                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14248                }
14249            }
14250            if (!brief) {
14251                if (!isCompact) {
14252                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14253                    pw.print(" kB (status ");
14254                    switch (mLastMemoryLevel) {
14255                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14256                            pw.println("normal)");
14257                            break;
14258                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14259                            pw.println("moderate)");
14260                            break;
14261                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14262                            pw.println("low)");
14263                            break;
14264                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14265                            pw.println("critical)");
14266                            break;
14267                        default:
14268                            pw.print(mLastMemoryLevel);
14269                            pw.println(")");
14270                            break;
14271                    }
14272                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14273                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14274                            pw.print(cachedPss); pw.print(" cached pss + ");
14275                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14276                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14277                } else {
14278                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14279                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14280                            + memInfo.getFreeSizeKb()); pw.print(",");
14281                    pw.println(totalPss - cachedPss);
14282                }
14283            }
14284            if (!isCompact) {
14285                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14286                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14287                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14288                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14289                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14290                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14291                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14292            }
14293            if (!brief) {
14294                if (memInfo.getZramTotalSizeKb() != 0) {
14295                    if (!isCompact) {
14296                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14297                                pw.print(" kB physical used for ");
14298                                pw.print(memInfo.getSwapTotalSizeKb()
14299                                        - memInfo.getSwapFreeSizeKb());
14300                                pw.print(" kB in swap (");
14301                                pw.print(memInfo.getSwapTotalSizeKb());
14302                                pw.println(" kB total swap)");
14303                    } else {
14304                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14305                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14306                                pw.println(memInfo.getSwapFreeSizeKb());
14307                    }
14308                }
14309                final long[] ksm = getKsmInfo();
14310                if (!isCompact) {
14311                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14312                            || ksm[KSM_VOLATILE] != 0) {
14313                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14314                                pw.print(" kB saved from shared ");
14315                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14316                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14317                                pw.print(" kB unshared; ");
14318                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14319                    }
14320                    pw.print("   Tuning: ");
14321                    pw.print(ActivityManager.staticGetMemoryClass());
14322                    pw.print(" (large ");
14323                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14324                    pw.print("), oom ");
14325                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14326                    pw.print(" kB");
14327                    pw.print(", restore limit ");
14328                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14329                    pw.print(" kB");
14330                    if (ActivityManager.isLowRamDeviceStatic()) {
14331                        pw.print(" (low-ram)");
14332                    }
14333                    if (ActivityManager.isHighEndGfx()) {
14334                        pw.print(" (high-end-gfx)");
14335                    }
14336                    pw.println();
14337                } else {
14338                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14339                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14340                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14341                    pw.print("tuning,");
14342                    pw.print(ActivityManager.staticGetMemoryClass());
14343                    pw.print(',');
14344                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14345                    pw.print(',');
14346                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14347                    if (ActivityManager.isLowRamDeviceStatic()) {
14348                        pw.print(",low-ram");
14349                    }
14350                    if (ActivityManager.isHighEndGfx()) {
14351                        pw.print(",high-end-gfx");
14352                    }
14353                    pw.println();
14354                }
14355            }
14356        }
14357    }
14358
14359    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14360            long memtrack, String name) {
14361        sb.append("  ");
14362        sb.append(ProcessList.makeOomAdjString(oomAdj));
14363        sb.append(' ');
14364        sb.append(ProcessList.makeProcStateString(procState));
14365        sb.append(' ');
14366        ProcessList.appendRamKb(sb, pss);
14367        sb.append(" kB: ");
14368        sb.append(name);
14369        if (memtrack > 0) {
14370            sb.append(" (");
14371            sb.append(memtrack);
14372            sb.append(" kB memtrack)");
14373        }
14374    }
14375
14376    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14377        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14378        sb.append(" (pid ");
14379        sb.append(mi.pid);
14380        sb.append(") ");
14381        sb.append(mi.adjType);
14382        sb.append('\n');
14383        if (mi.adjReason != null) {
14384            sb.append("                      ");
14385            sb.append(mi.adjReason);
14386            sb.append('\n');
14387        }
14388    }
14389
14390    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14391        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14392        for (int i=0, N=memInfos.size(); i<N; i++) {
14393            ProcessMemInfo mi = memInfos.get(i);
14394            infoMap.put(mi.pid, mi);
14395        }
14396        updateCpuStatsNow();
14397        long[] memtrackTmp = new long[1];
14398        synchronized (mProcessCpuTracker) {
14399            final int N = mProcessCpuTracker.countStats();
14400            for (int i=0; i<N; i++) {
14401                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14402                if (st.vsize > 0) {
14403                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14404                    if (pss > 0) {
14405                        if (infoMap.indexOfKey(st.pid) < 0) {
14406                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14407                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14408                            mi.pss = pss;
14409                            mi.memtrack = memtrackTmp[0];
14410                            memInfos.add(mi);
14411                        }
14412                    }
14413                }
14414            }
14415        }
14416
14417        long totalPss = 0;
14418        long totalMemtrack = 0;
14419        for (int i=0, N=memInfos.size(); i<N; i++) {
14420            ProcessMemInfo mi = memInfos.get(i);
14421            if (mi.pss == 0) {
14422                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14423                mi.memtrack = memtrackTmp[0];
14424            }
14425            totalPss += mi.pss;
14426            totalMemtrack += mi.memtrack;
14427        }
14428        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14429            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14430                if (lhs.oomAdj != rhs.oomAdj) {
14431                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14432                }
14433                if (lhs.pss != rhs.pss) {
14434                    return lhs.pss < rhs.pss ? 1 : -1;
14435                }
14436                return 0;
14437            }
14438        });
14439
14440        StringBuilder tag = new StringBuilder(128);
14441        StringBuilder stack = new StringBuilder(128);
14442        tag.append("Low on memory -- ");
14443        appendMemBucket(tag, totalPss, "total", false);
14444        appendMemBucket(stack, totalPss, "total", true);
14445
14446        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14447        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14448        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14449
14450        boolean firstLine = true;
14451        int lastOomAdj = Integer.MIN_VALUE;
14452        long extraNativeRam = 0;
14453        long extraNativeMemtrack = 0;
14454        long cachedPss = 0;
14455        for (int i=0, N=memInfos.size(); i<N; i++) {
14456            ProcessMemInfo mi = memInfos.get(i);
14457
14458            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14459                cachedPss += mi.pss;
14460            }
14461
14462            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14463                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14464                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14465                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14466                if (lastOomAdj != mi.oomAdj) {
14467                    lastOomAdj = mi.oomAdj;
14468                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14469                        tag.append(" / ");
14470                    }
14471                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14472                        if (firstLine) {
14473                            stack.append(":");
14474                            firstLine = false;
14475                        }
14476                        stack.append("\n\t at ");
14477                    } else {
14478                        stack.append("$");
14479                    }
14480                } else {
14481                    tag.append(" ");
14482                    stack.append("$");
14483                }
14484                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14485                    appendMemBucket(tag, mi.pss, mi.name, false);
14486                }
14487                appendMemBucket(stack, mi.pss, mi.name, true);
14488                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14489                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14490                    stack.append("(");
14491                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14492                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14493                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14494                            stack.append(":");
14495                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14496                        }
14497                    }
14498                    stack.append(")");
14499                }
14500            }
14501
14502            appendMemInfo(fullNativeBuilder, mi);
14503            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14504                // The short form only has native processes that are >= 512K.
14505                if (mi.pss >= 512) {
14506                    appendMemInfo(shortNativeBuilder, mi);
14507                } else {
14508                    extraNativeRam += mi.pss;
14509                    extraNativeMemtrack += mi.memtrack;
14510                }
14511            } else {
14512                // Short form has all other details, but if we have collected RAM
14513                // from smaller native processes let's dump a summary of that.
14514                if (extraNativeRam > 0) {
14515                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14516                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14517                    shortNativeBuilder.append('\n');
14518                    extraNativeRam = 0;
14519                }
14520                appendMemInfo(fullJavaBuilder, mi);
14521            }
14522        }
14523
14524        fullJavaBuilder.append("           ");
14525        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14526        fullJavaBuilder.append(" kB: TOTAL");
14527        if (totalMemtrack > 0) {
14528            fullJavaBuilder.append(" (");
14529            fullJavaBuilder.append(totalMemtrack);
14530            fullJavaBuilder.append(" kB memtrack)");
14531        } else {
14532        }
14533        fullJavaBuilder.append("\n");
14534
14535        MemInfoReader memInfo = new MemInfoReader();
14536        memInfo.readMemInfo();
14537        final long[] infos = memInfo.getRawInfo();
14538
14539        StringBuilder memInfoBuilder = new StringBuilder(1024);
14540        Debug.getMemInfo(infos);
14541        memInfoBuilder.append("  MemInfo: ");
14542        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14543        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14544        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14545        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14546        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14547        memInfoBuilder.append("           ");
14548        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14549        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14550        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14551        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14552        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14553            memInfoBuilder.append("  ZRAM: ");
14554            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14555            memInfoBuilder.append(" kB RAM, ");
14556            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14557            memInfoBuilder.append(" kB swap total, ");
14558            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14559            memInfoBuilder.append(" kB swap free\n");
14560        }
14561        final long[] ksm = getKsmInfo();
14562        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14563                || ksm[KSM_VOLATILE] != 0) {
14564            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14565            memInfoBuilder.append(" kB saved from shared ");
14566            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14567            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14568            memInfoBuilder.append(" kB unshared; ");
14569            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14570        }
14571        memInfoBuilder.append("  Free RAM: ");
14572        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14573                + memInfo.getFreeSizeKb());
14574        memInfoBuilder.append(" kB\n");
14575        memInfoBuilder.append("  Used RAM: ");
14576        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14577        memInfoBuilder.append(" kB\n");
14578        memInfoBuilder.append("  Lost RAM: ");
14579        memInfoBuilder.append(memInfo.getTotalSizeKb()
14580                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14581                - memInfo.getKernelUsedSizeKb());
14582        memInfoBuilder.append(" kB\n");
14583        Slog.i(TAG, "Low on memory:");
14584        Slog.i(TAG, shortNativeBuilder.toString());
14585        Slog.i(TAG, fullJavaBuilder.toString());
14586        Slog.i(TAG, memInfoBuilder.toString());
14587
14588        StringBuilder dropBuilder = new StringBuilder(1024);
14589        /*
14590        StringWriter oomSw = new StringWriter();
14591        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14592        StringWriter catSw = new StringWriter();
14593        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14594        String[] emptyArgs = new String[] { };
14595        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14596        oomPw.flush();
14597        String oomString = oomSw.toString();
14598        */
14599        dropBuilder.append("Low on memory:");
14600        dropBuilder.append(stack);
14601        dropBuilder.append('\n');
14602        dropBuilder.append(fullNativeBuilder);
14603        dropBuilder.append(fullJavaBuilder);
14604        dropBuilder.append('\n');
14605        dropBuilder.append(memInfoBuilder);
14606        dropBuilder.append('\n');
14607        /*
14608        dropBuilder.append(oomString);
14609        dropBuilder.append('\n');
14610        */
14611        StringWriter catSw = new StringWriter();
14612        synchronized (ActivityManagerService.this) {
14613            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14614            String[] emptyArgs = new String[] { };
14615            catPw.println();
14616            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14617            catPw.println();
14618            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14619                    false, false, null);
14620            catPw.println();
14621            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14622            catPw.flush();
14623        }
14624        dropBuilder.append(catSw.toString());
14625        addErrorToDropBox("lowmem", null, "system_server", null,
14626                null, tag.toString(), dropBuilder.toString(), null, null);
14627        //Slog.i(TAG, "Sent to dropbox:");
14628        //Slog.i(TAG, dropBuilder.toString());
14629        synchronized (ActivityManagerService.this) {
14630            long now = SystemClock.uptimeMillis();
14631            if (mLastMemUsageReportTime < now) {
14632                mLastMemUsageReportTime = now;
14633            }
14634        }
14635    }
14636
14637    /**
14638     * Searches array of arguments for the specified string
14639     * @param args array of argument strings
14640     * @param value value to search for
14641     * @return true if the value is contained in the array
14642     */
14643    private static boolean scanArgs(String[] args, String value) {
14644        if (args != null) {
14645            for (String arg : args) {
14646                if (value.equals(arg)) {
14647                    return true;
14648                }
14649            }
14650        }
14651        return false;
14652    }
14653
14654    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14655            ContentProviderRecord cpr, boolean always) {
14656        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14657
14658        if (!inLaunching || always) {
14659            synchronized (cpr) {
14660                cpr.launchingApp = null;
14661                cpr.notifyAll();
14662            }
14663            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14664            String names[] = cpr.info.authority.split(";");
14665            for (int j = 0; j < names.length; j++) {
14666                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14667            }
14668        }
14669
14670        for (int i=0; i<cpr.connections.size(); i++) {
14671            ContentProviderConnection conn = cpr.connections.get(i);
14672            if (conn.waiting) {
14673                // If this connection is waiting for the provider, then we don't
14674                // need to mess with its process unless we are always removing
14675                // or for some reason the provider is not currently launching.
14676                if (inLaunching && !always) {
14677                    continue;
14678                }
14679            }
14680            ProcessRecord capp = conn.client;
14681            conn.dead = true;
14682            if (conn.stableCount > 0) {
14683                if (!capp.persistent && capp.thread != null
14684                        && capp.pid != 0
14685                        && capp.pid != MY_PID) {
14686                    capp.kill("depends on provider "
14687                            + cpr.name.flattenToShortString()
14688                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14689                }
14690            } else if (capp.thread != null && conn.provider.provider != null) {
14691                try {
14692                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14693                } catch (RemoteException e) {
14694                }
14695                // In the protocol here, we don't expect the client to correctly
14696                // clean up this connection, we'll just remove it.
14697                cpr.connections.remove(i);
14698                conn.client.conProviders.remove(conn);
14699            }
14700        }
14701
14702        if (inLaunching && always) {
14703            mLaunchingProviders.remove(cpr);
14704        }
14705        return inLaunching;
14706    }
14707
14708    /**
14709     * Main code for cleaning up a process when it has gone away.  This is
14710     * called both as a result of the process dying, or directly when stopping
14711     * a process when running in single process mode.
14712     *
14713     * @return Returns true if the given process has been restarted, so the
14714     * app that was passed in must remain on the process lists.
14715     */
14716    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14717            boolean restarting, boolean allowRestart, int index) {
14718        if (index >= 0) {
14719            removeLruProcessLocked(app);
14720            ProcessList.remove(app.pid);
14721        }
14722
14723        mProcessesToGc.remove(app);
14724        mPendingPssProcesses.remove(app);
14725
14726        // Dismiss any open dialogs.
14727        if (app.crashDialog != null && !app.forceCrashReport) {
14728            app.crashDialog.dismiss();
14729            app.crashDialog = null;
14730        }
14731        if (app.anrDialog != null) {
14732            app.anrDialog.dismiss();
14733            app.anrDialog = null;
14734        }
14735        if (app.waitDialog != null) {
14736            app.waitDialog.dismiss();
14737            app.waitDialog = null;
14738        }
14739
14740        app.crashing = false;
14741        app.notResponding = false;
14742
14743        app.resetPackageList(mProcessStats);
14744        app.unlinkDeathRecipient();
14745        app.makeInactive(mProcessStats);
14746        app.waitingToKill = null;
14747        app.forcingToForeground = null;
14748        updateProcessForegroundLocked(app, false, false);
14749        app.foregroundActivities = false;
14750        app.hasShownUi = false;
14751        app.treatLikeActivity = false;
14752        app.hasAboveClient = false;
14753        app.hasClientActivities = false;
14754
14755        mServices.killServicesLocked(app, allowRestart);
14756
14757        boolean restart = false;
14758
14759        // Remove published content providers.
14760        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14761            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14762            final boolean always = app.bad || !allowRestart;
14763            if (removeDyingProviderLocked(app, cpr, always) || always) {
14764                // We left the provider in the launching list, need to
14765                // restart it.
14766                restart = true;
14767            }
14768
14769            cpr.provider = null;
14770            cpr.proc = null;
14771        }
14772        app.pubProviders.clear();
14773
14774        // Take care of any launching providers waiting for this process.
14775        if (checkAppInLaunchingProvidersLocked(app, false)) {
14776            restart = true;
14777        }
14778
14779        // Unregister from connected content providers.
14780        if (!app.conProviders.isEmpty()) {
14781            for (int i=0; i<app.conProviders.size(); i++) {
14782                ContentProviderConnection conn = app.conProviders.get(i);
14783                conn.provider.connections.remove(conn);
14784            }
14785            app.conProviders.clear();
14786        }
14787
14788        // At this point there may be remaining entries in mLaunchingProviders
14789        // where we were the only one waiting, so they are no longer of use.
14790        // Look for these and clean up if found.
14791        // XXX Commented out for now.  Trying to figure out a way to reproduce
14792        // the actual situation to identify what is actually going on.
14793        if (false) {
14794            for (int i=0; i<mLaunchingProviders.size(); i++) {
14795                ContentProviderRecord cpr = (ContentProviderRecord)
14796                        mLaunchingProviders.get(i);
14797                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14798                    synchronized (cpr) {
14799                        cpr.launchingApp = null;
14800                        cpr.notifyAll();
14801                    }
14802                }
14803            }
14804        }
14805
14806        skipCurrentReceiverLocked(app);
14807
14808        // Unregister any receivers.
14809        for (int i=app.receivers.size()-1; i>=0; i--) {
14810            removeReceiverLocked(app.receivers.valueAt(i));
14811        }
14812        app.receivers.clear();
14813
14814        // If the app is undergoing backup, tell the backup manager about it
14815        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14816            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14817                    + mBackupTarget.appInfo + " died during backup");
14818            try {
14819                IBackupManager bm = IBackupManager.Stub.asInterface(
14820                        ServiceManager.getService(Context.BACKUP_SERVICE));
14821                bm.agentDisconnected(app.info.packageName);
14822            } catch (RemoteException e) {
14823                // can't happen; backup manager is local
14824            }
14825        }
14826
14827        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14828            ProcessChangeItem item = mPendingProcessChanges.get(i);
14829            if (item.pid == app.pid) {
14830                mPendingProcessChanges.remove(i);
14831                mAvailProcessChanges.add(item);
14832            }
14833        }
14834        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14835
14836        // If the caller is restarting this app, then leave it in its
14837        // current lists and let the caller take care of it.
14838        if (restarting) {
14839            return false;
14840        }
14841
14842        if (!app.persistent || app.isolated) {
14843            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14844                    "Removing non-persistent process during cleanup: " + app);
14845            mProcessNames.remove(app.processName, app.uid);
14846            mIsolatedProcesses.remove(app.uid);
14847            if (mHeavyWeightProcess == app) {
14848                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14849                        mHeavyWeightProcess.userId, 0));
14850                mHeavyWeightProcess = null;
14851            }
14852        } else if (!app.removed) {
14853            // This app is persistent, so we need to keep its record around.
14854            // If it is not already on the pending app list, add it there
14855            // and start a new process for it.
14856            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14857                mPersistentStartingProcesses.add(app);
14858                restart = true;
14859            }
14860        }
14861        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14862                "Clean-up removing on hold: " + app);
14863        mProcessesOnHold.remove(app);
14864
14865        if (app == mHomeProcess) {
14866            mHomeProcess = null;
14867        }
14868        if (app == mPreviousProcess) {
14869            mPreviousProcess = null;
14870        }
14871
14872        if (restart && !app.isolated) {
14873            // We have components that still need to be running in the
14874            // process, so re-launch it.
14875            if (index < 0) {
14876                ProcessList.remove(app.pid);
14877            }
14878            mProcessNames.put(app.processName, app.uid, app);
14879            startProcessLocked(app, "restart", app.processName);
14880            return true;
14881        } else if (app.pid > 0 && app.pid != MY_PID) {
14882            // Goodbye!
14883            boolean removed;
14884            synchronized (mPidsSelfLocked) {
14885                mPidsSelfLocked.remove(app.pid);
14886                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14887            }
14888            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14889            if (app.isolated) {
14890                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14891            }
14892            app.setPid(0);
14893        }
14894        return false;
14895    }
14896
14897    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14898        // Look through the content providers we are waiting to have launched,
14899        // and if any run in this process then either schedule a restart of
14900        // the process or kill the client waiting for it if this process has
14901        // gone bad.
14902        int NL = mLaunchingProviders.size();
14903        boolean restart = false;
14904        for (int i=0; i<NL; i++) {
14905            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14906            if (cpr.launchingApp == app) {
14907                if (!alwaysBad && !app.bad) {
14908                    restart = true;
14909                } else {
14910                    removeDyingProviderLocked(app, cpr, true);
14911                    // cpr should have been removed from mLaunchingProviders
14912                    NL = mLaunchingProviders.size();
14913                    i--;
14914                }
14915            }
14916        }
14917        return restart;
14918    }
14919
14920    // =========================================================
14921    // SERVICES
14922    // =========================================================
14923
14924    @Override
14925    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14926            int flags) {
14927        enforceNotIsolatedCaller("getServices");
14928        synchronized (this) {
14929            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14930        }
14931    }
14932
14933    @Override
14934    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14935        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14936        synchronized (this) {
14937            return mServices.getRunningServiceControlPanelLocked(name);
14938        }
14939    }
14940
14941    @Override
14942    public ComponentName startService(IApplicationThread caller, Intent service,
14943            String resolvedType, int userId) {
14944        enforceNotIsolatedCaller("startService");
14945        // Refuse possible leaked file descriptors
14946        if (service != null && service.hasFileDescriptors() == true) {
14947            throw new IllegalArgumentException("File descriptors passed in Intent");
14948        }
14949
14950        if (DEBUG_SERVICE)
14951            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14952        synchronized(this) {
14953            final int callingPid = Binder.getCallingPid();
14954            final int callingUid = Binder.getCallingUid();
14955            final long origId = Binder.clearCallingIdentity();
14956            ComponentName res = mServices.startServiceLocked(caller, service,
14957                    resolvedType, callingPid, callingUid, userId);
14958            Binder.restoreCallingIdentity(origId);
14959            return res;
14960        }
14961    }
14962
14963    ComponentName startServiceInPackage(int uid,
14964            Intent service, String resolvedType, int userId) {
14965        synchronized(this) {
14966            if (DEBUG_SERVICE)
14967                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14968            final long origId = Binder.clearCallingIdentity();
14969            ComponentName res = mServices.startServiceLocked(null, service,
14970                    resolvedType, -1, uid, userId);
14971            Binder.restoreCallingIdentity(origId);
14972            return res;
14973        }
14974    }
14975
14976    @Override
14977    public int stopService(IApplicationThread caller, Intent service,
14978            String resolvedType, int userId) {
14979        enforceNotIsolatedCaller("stopService");
14980        // Refuse possible leaked file descriptors
14981        if (service != null && service.hasFileDescriptors() == true) {
14982            throw new IllegalArgumentException("File descriptors passed in Intent");
14983        }
14984
14985        synchronized(this) {
14986            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14987        }
14988    }
14989
14990    @Override
14991    public IBinder peekService(Intent service, String resolvedType) {
14992        enforceNotIsolatedCaller("peekService");
14993        // Refuse possible leaked file descriptors
14994        if (service != null && service.hasFileDescriptors() == true) {
14995            throw new IllegalArgumentException("File descriptors passed in Intent");
14996        }
14997        synchronized(this) {
14998            return mServices.peekServiceLocked(service, resolvedType);
14999        }
15000    }
15001
15002    @Override
15003    public boolean stopServiceToken(ComponentName className, IBinder token,
15004            int startId) {
15005        synchronized(this) {
15006            return mServices.stopServiceTokenLocked(className, token, startId);
15007        }
15008    }
15009
15010    @Override
15011    public void setServiceForeground(ComponentName className, IBinder token,
15012            int id, Notification notification, boolean removeNotification) {
15013        synchronized(this) {
15014            mServices.setServiceForegroundLocked(className, token, id, notification,
15015                    removeNotification);
15016        }
15017    }
15018
15019    @Override
15020    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15021            boolean requireFull, String name, String callerPackage) {
15022        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15023                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15024    }
15025
15026    int unsafeConvertIncomingUser(int userId) {
15027        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15028                ? mCurrentUserId : userId;
15029    }
15030
15031    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15032            int allowMode, String name, String callerPackage) {
15033        final int callingUserId = UserHandle.getUserId(callingUid);
15034        if (callingUserId == userId) {
15035            return userId;
15036        }
15037
15038        // Note that we may be accessing mCurrentUserId outside of a lock...
15039        // shouldn't be a big deal, if this is being called outside
15040        // of a locked context there is intrinsically a race with
15041        // the value the caller will receive and someone else changing it.
15042        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15043        // we will switch to the calling user if access to the current user fails.
15044        int targetUserId = unsafeConvertIncomingUser(userId);
15045
15046        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15047            final boolean allow;
15048            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15049                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15050                // If the caller has this permission, they always pass go.  And collect $200.
15051                allow = true;
15052            } else if (allowMode == ALLOW_FULL_ONLY) {
15053                // We require full access, sucks to be you.
15054                allow = false;
15055            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15056                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15057                // If the caller does not have either permission, they are always doomed.
15058                allow = false;
15059            } else if (allowMode == ALLOW_NON_FULL) {
15060                // We are blanket allowing non-full access, you lucky caller!
15061                allow = true;
15062            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15063                // We may or may not allow this depending on whether the two users are
15064                // in the same profile.
15065                synchronized (mUserProfileGroupIdsSelfLocked) {
15066                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15067                            UserInfo.NO_PROFILE_GROUP_ID);
15068                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15069                            UserInfo.NO_PROFILE_GROUP_ID);
15070                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15071                            && callingProfile == targetProfile;
15072                }
15073            } else {
15074                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15075            }
15076            if (!allow) {
15077                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15078                    // In this case, they would like to just execute as their
15079                    // owner user instead of failing.
15080                    targetUserId = callingUserId;
15081                } else {
15082                    StringBuilder builder = new StringBuilder(128);
15083                    builder.append("Permission Denial: ");
15084                    builder.append(name);
15085                    if (callerPackage != null) {
15086                        builder.append(" from ");
15087                        builder.append(callerPackage);
15088                    }
15089                    builder.append(" asks to run as user ");
15090                    builder.append(userId);
15091                    builder.append(" but is calling from user ");
15092                    builder.append(UserHandle.getUserId(callingUid));
15093                    builder.append("; this requires ");
15094                    builder.append(INTERACT_ACROSS_USERS_FULL);
15095                    if (allowMode != ALLOW_FULL_ONLY) {
15096                        builder.append(" or ");
15097                        builder.append(INTERACT_ACROSS_USERS);
15098                    }
15099                    String msg = builder.toString();
15100                    Slog.w(TAG, msg);
15101                    throw new SecurityException(msg);
15102                }
15103            }
15104        }
15105        if (!allowAll && targetUserId < 0) {
15106            throw new IllegalArgumentException(
15107                    "Call does not support special user #" + targetUserId);
15108        }
15109        // Check shell permission
15110        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15111            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15112                    targetUserId)) {
15113                throw new SecurityException("Shell does not have permission to access user "
15114                        + targetUserId + "\n " + Debug.getCallers(3));
15115            }
15116        }
15117        return targetUserId;
15118    }
15119
15120    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15121            String className, int flags) {
15122        boolean result = false;
15123        // For apps that don't have pre-defined UIDs, check for permission
15124        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15125            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15126                if (ActivityManager.checkUidPermission(
15127                        INTERACT_ACROSS_USERS,
15128                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15129                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15130                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15131                            + " requests FLAG_SINGLE_USER, but app does not hold "
15132                            + INTERACT_ACROSS_USERS;
15133                    Slog.w(TAG, msg);
15134                    throw new SecurityException(msg);
15135                }
15136                // Permission passed
15137                result = true;
15138            }
15139        } else if ("system".equals(componentProcessName)) {
15140            result = true;
15141        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15142            // Phone app and persistent apps are allowed to export singleuser providers.
15143            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15144                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15145        }
15146        if (DEBUG_MU) {
15147            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15148                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15149        }
15150        return result;
15151    }
15152
15153    /**
15154     * Checks to see if the caller is in the same app as the singleton
15155     * component, or the component is in a special app. It allows special apps
15156     * to export singleton components but prevents exporting singleton
15157     * components for regular apps.
15158     */
15159    boolean isValidSingletonCall(int callingUid, int componentUid) {
15160        int componentAppId = UserHandle.getAppId(componentUid);
15161        return UserHandle.isSameApp(callingUid, componentUid)
15162                || componentAppId == Process.SYSTEM_UID
15163                || componentAppId == Process.PHONE_UID
15164                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15165                        == PackageManager.PERMISSION_GRANTED;
15166    }
15167
15168    public int bindService(IApplicationThread caller, IBinder token,
15169            Intent service, String resolvedType,
15170            IServiceConnection connection, int flags, int userId) {
15171        enforceNotIsolatedCaller("bindService");
15172
15173        // Refuse possible leaked file descriptors
15174        if (service != null && service.hasFileDescriptors() == true) {
15175            throw new IllegalArgumentException("File descriptors passed in Intent");
15176        }
15177
15178        synchronized(this) {
15179            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15180                    connection, flags, userId);
15181        }
15182    }
15183
15184    public boolean unbindService(IServiceConnection connection) {
15185        synchronized (this) {
15186            return mServices.unbindServiceLocked(connection);
15187        }
15188    }
15189
15190    public void publishService(IBinder token, Intent intent, IBinder service) {
15191        // Refuse possible leaked file descriptors
15192        if (intent != null && intent.hasFileDescriptors() == true) {
15193            throw new IllegalArgumentException("File descriptors passed in Intent");
15194        }
15195
15196        synchronized(this) {
15197            if (!(token instanceof ServiceRecord)) {
15198                throw new IllegalArgumentException("Invalid service token");
15199            }
15200            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15201        }
15202    }
15203
15204    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15205        // Refuse possible leaked file descriptors
15206        if (intent != null && intent.hasFileDescriptors() == true) {
15207            throw new IllegalArgumentException("File descriptors passed in Intent");
15208        }
15209
15210        synchronized(this) {
15211            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15212        }
15213    }
15214
15215    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15216        synchronized(this) {
15217            if (!(token instanceof ServiceRecord)) {
15218                throw new IllegalArgumentException("Invalid service token");
15219            }
15220            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15221        }
15222    }
15223
15224    // =========================================================
15225    // BACKUP AND RESTORE
15226    // =========================================================
15227
15228    // Cause the target app to be launched if necessary and its backup agent
15229    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15230    // activity manager to announce its creation.
15231    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15232        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15233        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15234
15235        synchronized(this) {
15236            // !!! TODO: currently no check here that we're already bound
15237            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15238            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15239            synchronized (stats) {
15240                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15241            }
15242
15243            // Backup agent is now in use, its package can't be stopped.
15244            try {
15245                AppGlobals.getPackageManager().setPackageStoppedState(
15246                        app.packageName, false, UserHandle.getUserId(app.uid));
15247            } catch (RemoteException e) {
15248            } catch (IllegalArgumentException e) {
15249                Slog.w(TAG, "Failed trying to unstop package "
15250                        + app.packageName + ": " + e);
15251            }
15252
15253            BackupRecord r = new BackupRecord(ss, app, backupMode);
15254            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15255                    ? new ComponentName(app.packageName, app.backupAgentName)
15256                    : new ComponentName("android", "FullBackupAgent");
15257            // startProcessLocked() returns existing proc's record if it's already running
15258            ProcessRecord proc = startProcessLocked(app.processName, app,
15259                    false, 0, "backup", hostingName, false, false, false);
15260            if (proc == null) {
15261                Slog.e(TAG, "Unable to start backup agent process " + r);
15262                return false;
15263            }
15264
15265            r.app = proc;
15266            mBackupTarget = r;
15267            mBackupAppName = app.packageName;
15268
15269            // Try not to kill the process during backup
15270            updateOomAdjLocked(proc);
15271
15272            // If the process is already attached, schedule the creation of the backup agent now.
15273            // If it is not yet live, this will be done when it attaches to the framework.
15274            if (proc.thread != null) {
15275                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15276                try {
15277                    proc.thread.scheduleCreateBackupAgent(app,
15278                            compatibilityInfoForPackageLocked(app), backupMode);
15279                } catch (RemoteException e) {
15280                    // Will time out on the backup manager side
15281                }
15282            } else {
15283                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15284            }
15285            // Invariants: at this point, the target app process exists and the application
15286            // is either already running or in the process of coming up.  mBackupTarget and
15287            // mBackupAppName describe the app, so that when it binds back to the AM we
15288            // know that it's scheduled for a backup-agent operation.
15289        }
15290
15291        return true;
15292    }
15293
15294    @Override
15295    public void clearPendingBackup() {
15296        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15297        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15298
15299        synchronized (this) {
15300            mBackupTarget = null;
15301            mBackupAppName = null;
15302        }
15303    }
15304
15305    // A backup agent has just come up
15306    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15307        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15308                + " = " + agent);
15309
15310        synchronized(this) {
15311            if (!agentPackageName.equals(mBackupAppName)) {
15312                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15313                return;
15314            }
15315        }
15316
15317        long oldIdent = Binder.clearCallingIdentity();
15318        try {
15319            IBackupManager bm = IBackupManager.Stub.asInterface(
15320                    ServiceManager.getService(Context.BACKUP_SERVICE));
15321            bm.agentConnected(agentPackageName, agent);
15322        } catch (RemoteException e) {
15323            // can't happen; the backup manager service is local
15324        } catch (Exception e) {
15325            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15326            e.printStackTrace();
15327        } finally {
15328            Binder.restoreCallingIdentity(oldIdent);
15329        }
15330    }
15331
15332    // done with this agent
15333    public void unbindBackupAgent(ApplicationInfo appInfo) {
15334        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15335        if (appInfo == null) {
15336            Slog.w(TAG, "unbind backup agent for null app");
15337            return;
15338        }
15339
15340        synchronized(this) {
15341            try {
15342                if (mBackupAppName == null) {
15343                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15344                    return;
15345                }
15346
15347                if (!mBackupAppName.equals(appInfo.packageName)) {
15348                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15349                    return;
15350                }
15351
15352                // Not backing this app up any more; reset its OOM adjustment
15353                final ProcessRecord proc = mBackupTarget.app;
15354                updateOomAdjLocked(proc);
15355
15356                // If the app crashed during backup, 'thread' will be null here
15357                if (proc.thread != null) {
15358                    try {
15359                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15360                                compatibilityInfoForPackageLocked(appInfo));
15361                    } catch (Exception e) {
15362                        Slog.e(TAG, "Exception when unbinding backup agent:");
15363                        e.printStackTrace();
15364                    }
15365                }
15366            } finally {
15367                mBackupTarget = null;
15368                mBackupAppName = null;
15369            }
15370        }
15371    }
15372    // =========================================================
15373    // BROADCASTS
15374    // =========================================================
15375
15376    private final List getStickiesLocked(String action, IntentFilter filter,
15377            List cur, int userId) {
15378        final ContentResolver resolver = mContext.getContentResolver();
15379        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15380        if (stickies == null) {
15381            return cur;
15382        }
15383        final ArrayList<Intent> list = stickies.get(action);
15384        if (list == null) {
15385            return cur;
15386        }
15387        int N = list.size();
15388        for (int i=0; i<N; i++) {
15389            Intent intent = list.get(i);
15390            if (filter.match(resolver, intent, true, TAG) >= 0) {
15391                if (cur == null) {
15392                    cur = new ArrayList<Intent>();
15393                }
15394                cur.add(intent);
15395            }
15396        }
15397        return cur;
15398    }
15399
15400    boolean isPendingBroadcastProcessLocked(int pid) {
15401        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15402                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15403    }
15404
15405    void skipPendingBroadcastLocked(int pid) {
15406            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15407            for (BroadcastQueue queue : mBroadcastQueues) {
15408                queue.skipPendingBroadcastLocked(pid);
15409            }
15410    }
15411
15412    // The app just attached; send any pending broadcasts that it should receive
15413    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15414        boolean didSomething = false;
15415        for (BroadcastQueue queue : mBroadcastQueues) {
15416            didSomething |= queue.sendPendingBroadcastsLocked(app);
15417        }
15418        return didSomething;
15419    }
15420
15421    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15422            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15423        enforceNotIsolatedCaller("registerReceiver");
15424        int callingUid;
15425        int callingPid;
15426        synchronized(this) {
15427            ProcessRecord callerApp = null;
15428            if (caller != null) {
15429                callerApp = getRecordForAppLocked(caller);
15430                if (callerApp == null) {
15431                    throw new SecurityException(
15432                            "Unable to find app for caller " + caller
15433                            + " (pid=" + Binder.getCallingPid()
15434                            + ") when registering receiver " + receiver);
15435                }
15436                if (callerApp.info.uid != Process.SYSTEM_UID &&
15437                        !callerApp.pkgList.containsKey(callerPackage) &&
15438                        !"android".equals(callerPackage)) {
15439                    throw new SecurityException("Given caller package " + callerPackage
15440                            + " is not running in process " + callerApp);
15441                }
15442                callingUid = callerApp.info.uid;
15443                callingPid = callerApp.pid;
15444            } else {
15445                callerPackage = null;
15446                callingUid = Binder.getCallingUid();
15447                callingPid = Binder.getCallingPid();
15448            }
15449
15450            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15451                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15452
15453            List allSticky = null;
15454
15455            // Look for any matching sticky broadcasts...
15456            Iterator actions = filter.actionsIterator();
15457            if (actions != null) {
15458                while (actions.hasNext()) {
15459                    String action = (String)actions.next();
15460                    allSticky = getStickiesLocked(action, filter, allSticky,
15461                            UserHandle.USER_ALL);
15462                    allSticky = getStickiesLocked(action, filter, allSticky,
15463                            UserHandle.getUserId(callingUid));
15464                }
15465            } else {
15466                allSticky = getStickiesLocked(null, filter, allSticky,
15467                        UserHandle.USER_ALL);
15468                allSticky = getStickiesLocked(null, filter, allSticky,
15469                        UserHandle.getUserId(callingUid));
15470            }
15471
15472            // The first sticky in the list is returned directly back to
15473            // the client.
15474            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15475
15476            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15477                    + ": " + sticky);
15478
15479            if (receiver == null) {
15480                return sticky;
15481            }
15482
15483            ReceiverList rl
15484                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15485            if (rl == null) {
15486                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15487                        userId, receiver);
15488                if (rl.app != null) {
15489                    rl.app.receivers.add(rl);
15490                } else {
15491                    try {
15492                        receiver.asBinder().linkToDeath(rl, 0);
15493                    } catch (RemoteException e) {
15494                        return sticky;
15495                    }
15496                    rl.linkedToDeath = true;
15497                }
15498                mRegisteredReceivers.put(receiver.asBinder(), rl);
15499            } else if (rl.uid != callingUid) {
15500                throw new IllegalArgumentException(
15501                        "Receiver requested to register for uid " + callingUid
15502                        + " was previously registered for uid " + rl.uid);
15503            } else if (rl.pid != callingPid) {
15504                throw new IllegalArgumentException(
15505                        "Receiver requested to register for pid " + callingPid
15506                        + " was previously registered for pid " + rl.pid);
15507            } else if (rl.userId != userId) {
15508                throw new IllegalArgumentException(
15509                        "Receiver requested to register for user " + userId
15510                        + " was previously registered for user " + rl.userId);
15511            }
15512            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15513                    permission, callingUid, userId);
15514            rl.add(bf);
15515            if (!bf.debugCheck()) {
15516                Slog.w(TAG, "==> For Dynamic broadast");
15517            }
15518            mReceiverResolver.addFilter(bf);
15519
15520            // Enqueue broadcasts for all existing stickies that match
15521            // this filter.
15522            if (allSticky != null) {
15523                ArrayList receivers = new ArrayList();
15524                receivers.add(bf);
15525
15526                int N = allSticky.size();
15527                for (int i=0; i<N; i++) {
15528                    Intent intent = (Intent)allSticky.get(i);
15529                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15530                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15531                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15532                            null, null, false, true, true, -1);
15533                    queue.enqueueParallelBroadcastLocked(r);
15534                    queue.scheduleBroadcastsLocked();
15535                }
15536            }
15537
15538            return sticky;
15539        }
15540    }
15541
15542    public void unregisterReceiver(IIntentReceiver receiver) {
15543        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15544
15545        final long origId = Binder.clearCallingIdentity();
15546        try {
15547            boolean doTrim = false;
15548
15549            synchronized(this) {
15550                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15551                if (rl != null) {
15552                    if (rl.curBroadcast != null) {
15553                        BroadcastRecord r = rl.curBroadcast;
15554                        final boolean doNext = finishReceiverLocked(
15555                                receiver.asBinder(), r.resultCode, r.resultData,
15556                                r.resultExtras, r.resultAbort);
15557                        if (doNext) {
15558                            doTrim = true;
15559                            r.queue.processNextBroadcast(false);
15560                        }
15561                    }
15562
15563                    if (rl.app != null) {
15564                        rl.app.receivers.remove(rl);
15565                    }
15566                    removeReceiverLocked(rl);
15567                    if (rl.linkedToDeath) {
15568                        rl.linkedToDeath = false;
15569                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15570                    }
15571                }
15572            }
15573
15574            // If we actually concluded any broadcasts, we might now be able
15575            // to trim the recipients' apps from our working set
15576            if (doTrim) {
15577                trimApplications();
15578                return;
15579            }
15580
15581        } finally {
15582            Binder.restoreCallingIdentity(origId);
15583        }
15584    }
15585
15586    void removeReceiverLocked(ReceiverList rl) {
15587        mRegisteredReceivers.remove(rl.receiver.asBinder());
15588        int N = rl.size();
15589        for (int i=0; i<N; i++) {
15590            mReceiverResolver.removeFilter(rl.get(i));
15591        }
15592    }
15593
15594    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15595        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15596            ProcessRecord r = mLruProcesses.get(i);
15597            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15598                try {
15599                    r.thread.dispatchPackageBroadcast(cmd, packages);
15600                } catch (RemoteException ex) {
15601                }
15602            }
15603        }
15604    }
15605
15606    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15607            int callingUid, int[] users) {
15608        List<ResolveInfo> receivers = null;
15609        try {
15610            HashSet<ComponentName> singleUserReceivers = null;
15611            boolean scannedFirstReceivers = false;
15612            for (int user : users) {
15613                // Skip users that have Shell restrictions
15614                if (callingUid == Process.SHELL_UID
15615                        && getUserManagerLocked().hasUserRestriction(
15616                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15617                    continue;
15618                }
15619                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15620                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15621                if (user != 0 && newReceivers != null) {
15622                    // If this is not the primary user, we need to check for
15623                    // any receivers that should be filtered out.
15624                    for (int i=0; i<newReceivers.size(); i++) {
15625                        ResolveInfo ri = newReceivers.get(i);
15626                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15627                            newReceivers.remove(i);
15628                            i--;
15629                        }
15630                    }
15631                }
15632                if (newReceivers != null && newReceivers.size() == 0) {
15633                    newReceivers = null;
15634                }
15635                if (receivers == null) {
15636                    receivers = newReceivers;
15637                } else if (newReceivers != null) {
15638                    // We need to concatenate the additional receivers
15639                    // found with what we have do far.  This would be easy,
15640                    // but we also need to de-dup any receivers that are
15641                    // singleUser.
15642                    if (!scannedFirstReceivers) {
15643                        // Collect any single user receivers we had already retrieved.
15644                        scannedFirstReceivers = true;
15645                        for (int i=0; i<receivers.size(); i++) {
15646                            ResolveInfo ri = receivers.get(i);
15647                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15648                                ComponentName cn = new ComponentName(
15649                                        ri.activityInfo.packageName, ri.activityInfo.name);
15650                                if (singleUserReceivers == null) {
15651                                    singleUserReceivers = new HashSet<ComponentName>();
15652                                }
15653                                singleUserReceivers.add(cn);
15654                            }
15655                        }
15656                    }
15657                    // Add the new results to the existing results, tracking
15658                    // and de-dupping single user receivers.
15659                    for (int i=0; i<newReceivers.size(); i++) {
15660                        ResolveInfo ri = newReceivers.get(i);
15661                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15662                            ComponentName cn = new ComponentName(
15663                                    ri.activityInfo.packageName, ri.activityInfo.name);
15664                            if (singleUserReceivers == null) {
15665                                singleUserReceivers = new HashSet<ComponentName>();
15666                            }
15667                            if (!singleUserReceivers.contains(cn)) {
15668                                singleUserReceivers.add(cn);
15669                                receivers.add(ri);
15670                            }
15671                        } else {
15672                            receivers.add(ri);
15673                        }
15674                    }
15675                }
15676            }
15677        } catch (RemoteException ex) {
15678            // pm is in same process, this will never happen.
15679        }
15680        return receivers;
15681    }
15682
15683    private final int broadcastIntentLocked(ProcessRecord callerApp,
15684            String callerPackage, Intent intent, String resolvedType,
15685            IIntentReceiver resultTo, int resultCode, String resultData,
15686            Bundle map, String requiredPermission, int appOp,
15687            boolean ordered, boolean sticky, int callingPid, int callingUid,
15688            int userId) {
15689        intent = new Intent(intent);
15690
15691        // By default broadcasts do not go to stopped apps.
15692        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15693
15694        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15695            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15696            + " ordered=" + ordered + " userid=" + userId);
15697        if ((resultTo != null) && !ordered) {
15698            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15699        }
15700
15701        userId = handleIncomingUser(callingPid, callingUid, userId,
15702                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15703
15704        // Make sure that the user who is receiving this broadcast is running.
15705        // If not, we will just skip it. Make an exception for shutdown broadcasts
15706        // and upgrade steps.
15707
15708        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15709            if ((callingUid != Process.SYSTEM_UID
15710                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15711                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15712                Slog.w(TAG, "Skipping broadcast of " + intent
15713                        + ": user " + userId + " is stopped");
15714                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15715            }
15716        }
15717
15718        /*
15719         * Prevent non-system code (defined here to be non-persistent
15720         * processes) from sending protected broadcasts.
15721         */
15722        int callingAppId = UserHandle.getAppId(callingUid);
15723        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15724            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15725            || callingAppId == Process.NFC_UID || callingUid == 0) {
15726            // Always okay.
15727        } else if (callerApp == null || !callerApp.persistent) {
15728            try {
15729                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15730                        intent.getAction())) {
15731                    String msg = "Permission Denial: not allowed to send broadcast "
15732                            + intent.getAction() + " from pid="
15733                            + callingPid + ", uid=" + callingUid;
15734                    Slog.w(TAG, msg);
15735                    throw new SecurityException(msg);
15736                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15737                    // Special case for compatibility: we don't want apps to send this,
15738                    // but historically it has not been protected and apps may be using it
15739                    // to poke their own app widget.  So, instead of making it protected,
15740                    // just limit it to the caller.
15741                    if (callerApp == null) {
15742                        String msg = "Permission Denial: not allowed to send broadcast "
15743                                + intent.getAction() + " from unknown caller.";
15744                        Slog.w(TAG, msg);
15745                        throw new SecurityException(msg);
15746                    } else if (intent.getComponent() != null) {
15747                        // They are good enough to send to an explicit component...  verify
15748                        // it is being sent to the calling app.
15749                        if (!intent.getComponent().getPackageName().equals(
15750                                callerApp.info.packageName)) {
15751                            String msg = "Permission Denial: not allowed to send broadcast "
15752                                    + intent.getAction() + " to "
15753                                    + intent.getComponent().getPackageName() + " from "
15754                                    + callerApp.info.packageName;
15755                            Slog.w(TAG, msg);
15756                            throw new SecurityException(msg);
15757                        }
15758                    } else {
15759                        // Limit broadcast to their own package.
15760                        intent.setPackage(callerApp.info.packageName);
15761                    }
15762                }
15763            } catch (RemoteException e) {
15764                Slog.w(TAG, "Remote exception", e);
15765                return ActivityManager.BROADCAST_SUCCESS;
15766            }
15767        }
15768
15769        final String action = intent.getAction();
15770        if (action != null) {
15771            switch (action) {
15772                case Intent.ACTION_UID_REMOVED:
15773                case Intent.ACTION_PACKAGE_REMOVED:
15774                case Intent.ACTION_PACKAGE_CHANGED:
15775                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15776                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15777                    // Handle special intents: if this broadcast is from the package
15778                    // manager about a package being removed, we need to remove all of
15779                    // its activities from the history stack.
15780                    if (checkComponentPermission(
15781                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15782                            callingPid, callingUid, -1, true)
15783                            != PackageManager.PERMISSION_GRANTED) {
15784                        String msg = "Permission Denial: " + intent.getAction()
15785                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15786                                + ", uid=" + callingUid + ")"
15787                                + " requires "
15788                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15789                        Slog.w(TAG, msg);
15790                        throw new SecurityException(msg);
15791                    }
15792                    switch (action) {
15793                        case Intent.ACTION_UID_REMOVED:
15794                            final Bundle intentExtras = intent.getExtras();
15795                            final int uid = intentExtras != null
15796                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15797                            if (uid >= 0) {
15798                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15799                                synchronized (bs) {
15800                                    bs.removeUidStatsLocked(uid);
15801                                }
15802                                mAppOpsService.uidRemoved(uid);
15803                            }
15804                            break;
15805                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15806                            // If resources are unavailable just force stop all those packages
15807                            // and flush the attribute cache as well.
15808                            String list[] =
15809                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15810                            if (list != null && list.length > 0) {
15811                                for (int i = 0; i < list.length; i++) {
15812                                    forceStopPackageLocked(list[i], -1, false, true, true,
15813                                            false, false, userId, "storage unmount");
15814                                }
15815                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15816                                sendPackageBroadcastLocked(
15817                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15818                                        userId);
15819                            }
15820                            break;
15821                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15822                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15823                            break;
15824                        case Intent.ACTION_PACKAGE_REMOVED:
15825                        case Intent.ACTION_PACKAGE_CHANGED:
15826                            Uri data = intent.getData();
15827                            String ssp;
15828                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15829                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15830                                boolean fullUninstall = removed &&
15831                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15832                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15833                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15834                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15835                                            false, true, true, false, fullUninstall, userId,
15836                                            removed ? "pkg removed" : "pkg changed");
15837                                }
15838                                if (removed) {
15839                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15840                                            new String[] {ssp}, userId);
15841                                    if (fullUninstall) {
15842                                        mAppOpsService.packageRemoved(
15843                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15844
15845                                        // Remove all permissions granted from/to this package
15846                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15847
15848                                        removeTasksByPackageNameLocked(ssp, userId);
15849                                    }
15850                                } else {
15851                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15852                                    if (userId == UserHandle.USER_OWNER) {
15853                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15854                                    }
15855                                }
15856                            }
15857                            break;
15858                    }
15859                    break;
15860                case Intent.ACTION_PACKAGE_ADDED:
15861                    // Special case for adding a package: by default turn on compatibility mode.
15862                    Uri data = intent.getData();
15863                    String ssp;
15864                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15865                        final boolean replacing =
15866                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15867                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15868
15869                        if (replacing) {
15870                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15871                        }
15872                        if (userId == UserHandle.USER_OWNER) {
15873                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15874                        }
15875                    }
15876                    break;
15877                case Intent.ACTION_TIMEZONE_CHANGED:
15878                    // If this is the time zone changed action, queue up a message that will reset
15879                    // the timezone of all currently running processes. This message will get
15880                    // queued up before the broadcast happens.
15881                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15882                    break;
15883                case Intent.ACTION_TIME_CHANGED:
15884                    // If the user set the time, let all running processes know.
15885                    final int is24Hour =
15886                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15887                                    : 0;
15888                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15889                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15890                    synchronized (stats) {
15891                        stats.noteCurrentTimeChangedLocked();
15892                    }
15893                    break;
15894                case Intent.ACTION_CLEAR_DNS_CACHE:
15895                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15896                    break;
15897                case Proxy.PROXY_CHANGE_ACTION:
15898                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15899                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15900                    break;
15901            }
15902        }
15903
15904        // Add to the sticky list if requested.
15905        if (sticky) {
15906            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15907                    callingPid, callingUid)
15908                    != PackageManager.PERMISSION_GRANTED) {
15909                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15910                        + callingPid + ", uid=" + callingUid
15911                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15912                Slog.w(TAG, msg);
15913                throw new SecurityException(msg);
15914            }
15915            if (requiredPermission != null) {
15916                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15917                        + " and enforce permission " + requiredPermission);
15918                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15919            }
15920            if (intent.getComponent() != null) {
15921                throw new SecurityException(
15922                        "Sticky broadcasts can't target a specific component");
15923            }
15924            // We use userId directly here, since the "all" target is maintained
15925            // as a separate set of sticky broadcasts.
15926            if (userId != UserHandle.USER_ALL) {
15927                // But first, if this is not a broadcast to all users, then
15928                // make sure it doesn't conflict with an existing broadcast to
15929                // all users.
15930                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15931                        UserHandle.USER_ALL);
15932                if (stickies != null) {
15933                    ArrayList<Intent> list = stickies.get(intent.getAction());
15934                    if (list != null) {
15935                        int N = list.size();
15936                        int i;
15937                        for (i=0; i<N; i++) {
15938                            if (intent.filterEquals(list.get(i))) {
15939                                throw new IllegalArgumentException(
15940                                        "Sticky broadcast " + intent + " for user "
15941                                        + userId + " conflicts with existing global broadcast");
15942                            }
15943                        }
15944                    }
15945                }
15946            }
15947            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15948            if (stickies == null) {
15949                stickies = new ArrayMap<String, ArrayList<Intent>>();
15950                mStickyBroadcasts.put(userId, stickies);
15951            }
15952            ArrayList<Intent> list = stickies.get(intent.getAction());
15953            if (list == null) {
15954                list = new ArrayList<Intent>();
15955                stickies.put(intent.getAction(), list);
15956            }
15957            int N = list.size();
15958            int i;
15959            for (i=0; i<N; i++) {
15960                if (intent.filterEquals(list.get(i))) {
15961                    // This sticky already exists, replace it.
15962                    list.set(i, new Intent(intent));
15963                    break;
15964                }
15965            }
15966            if (i >= N) {
15967                list.add(new Intent(intent));
15968            }
15969        }
15970
15971        int[] users;
15972        if (userId == UserHandle.USER_ALL) {
15973            // Caller wants broadcast to go to all started users.
15974            users = mStartedUserArray;
15975        } else {
15976            // Caller wants broadcast to go to one specific user.
15977            users = new int[] {userId};
15978        }
15979
15980        // Figure out who all will receive this broadcast.
15981        List receivers = null;
15982        List<BroadcastFilter> registeredReceivers = null;
15983        // Need to resolve the intent to interested receivers...
15984        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15985                 == 0) {
15986            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15987        }
15988        if (intent.getComponent() == null) {
15989            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15990                // Query one target user at a time, excluding shell-restricted users
15991                UserManagerService ums = getUserManagerLocked();
15992                for (int i = 0; i < users.length; i++) {
15993                    if (ums.hasUserRestriction(
15994                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15995                        continue;
15996                    }
15997                    List<BroadcastFilter> registeredReceiversForUser =
15998                            mReceiverResolver.queryIntent(intent,
15999                                    resolvedType, false, users[i]);
16000                    if (registeredReceivers == null) {
16001                        registeredReceivers = registeredReceiversForUser;
16002                    } else if (registeredReceiversForUser != null) {
16003                        registeredReceivers.addAll(registeredReceiversForUser);
16004                    }
16005                }
16006            } else {
16007                registeredReceivers = mReceiverResolver.queryIntent(intent,
16008                        resolvedType, false, userId);
16009            }
16010        }
16011
16012        final boolean replacePending =
16013                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16014
16015        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16016                + " replacePending=" + replacePending);
16017
16018        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16019        if (!ordered && NR > 0) {
16020            // If we are not serializing this broadcast, then send the
16021            // registered receivers separately so they don't wait for the
16022            // components to be launched.
16023            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16024            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16025                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16026                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16027                    ordered, sticky, false, userId);
16028            if (DEBUG_BROADCAST) Slog.v(
16029                    TAG, "Enqueueing parallel broadcast " + r);
16030            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16031            if (!replaced) {
16032                queue.enqueueParallelBroadcastLocked(r);
16033                queue.scheduleBroadcastsLocked();
16034            }
16035            registeredReceivers = null;
16036            NR = 0;
16037        }
16038
16039        // Merge into one list.
16040        int ir = 0;
16041        if (receivers != null) {
16042            // A special case for PACKAGE_ADDED: do not allow the package
16043            // being added to see this broadcast.  This prevents them from
16044            // using this as a back door to get run as soon as they are
16045            // installed.  Maybe in the future we want to have a special install
16046            // broadcast or such for apps, but we'd like to deliberately make
16047            // this decision.
16048            String skipPackages[] = null;
16049            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16050                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16051                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16052                Uri data = intent.getData();
16053                if (data != null) {
16054                    String pkgName = data.getSchemeSpecificPart();
16055                    if (pkgName != null) {
16056                        skipPackages = new String[] { pkgName };
16057                    }
16058                }
16059            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16060                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16061            }
16062            if (skipPackages != null && (skipPackages.length > 0)) {
16063                for (String skipPackage : skipPackages) {
16064                    if (skipPackage != null) {
16065                        int NT = receivers.size();
16066                        for (int it=0; it<NT; it++) {
16067                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16068                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16069                                receivers.remove(it);
16070                                it--;
16071                                NT--;
16072                            }
16073                        }
16074                    }
16075                }
16076            }
16077
16078            int NT = receivers != null ? receivers.size() : 0;
16079            int it = 0;
16080            ResolveInfo curt = null;
16081            BroadcastFilter curr = null;
16082            while (it < NT && ir < NR) {
16083                if (curt == null) {
16084                    curt = (ResolveInfo)receivers.get(it);
16085                }
16086                if (curr == null) {
16087                    curr = registeredReceivers.get(ir);
16088                }
16089                if (curr.getPriority() >= curt.priority) {
16090                    // Insert this broadcast record into the final list.
16091                    receivers.add(it, curr);
16092                    ir++;
16093                    curr = null;
16094                    it++;
16095                    NT++;
16096                } else {
16097                    // Skip to the next ResolveInfo in the final list.
16098                    it++;
16099                    curt = null;
16100                }
16101            }
16102        }
16103        while (ir < NR) {
16104            if (receivers == null) {
16105                receivers = new ArrayList();
16106            }
16107            receivers.add(registeredReceivers.get(ir));
16108            ir++;
16109        }
16110
16111        if ((receivers != null && receivers.size() > 0)
16112                || resultTo != null) {
16113            BroadcastQueue queue = broadcastQueueForIntent(intent);
16114            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16115                    callerPackage, callingPid, callingUid, resolvedType,
16116                    requiredPermission, appOp, receivers, resultTo, resultCode,
16117                    resultData, map, ordered, sticky, false, userId);
16118            if (DEBUG_BROADCAST) Slog.v(
16119                    TAG, "Enqueueing ordered broadcast " + r
16120                    + ": prev had " + queue.mOrderedBroadcasts.size());
16121            if (DEBUG_BROADCAST) {
16122                int seq = r.intent.getIntExtra("seq", -1);
16123                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16124            }
16125            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16126            if (!replaced) {
16127                queue.enqueueOrderedBroadcastLocked(r);
16128                queue.scheduleBroadcastsLocked();
16129            }
16130        }
16131
16132        return ActivityManager.BROADCAST_SUCCESS;
16133    }
16134
16135    final Intent verifyBroadcastLocked(Intent intent) {
16136        // Refuse possible leaked file descriptors
16137        if (intent != null && intent.hasFileDescriptors() == true) {
16138            throw new IllegalArgumentException("File descriptors passed in Intent");
16139        }
16140
16141        int flags = intent.getFlags();
16142
16143        if (!mProcessesReady) {
16144            // if the caller really truly claims to know what they're doing, go
16145            // ahead and allow the broadcast without launching any receivers
16146            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16147                intent = new Intent(intent);
16148                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16149            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16150                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16151                        + " before boot completion");
16152                throw new IllegalStateException("Cannot broadcast before boot completed");
16153            }
16154        }
16155
16156        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16157            throw new IllegalArgumentException(
16158                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16159        }
16160
16161        return intent;
16162    }
16163
16164    public final int broadcastIntent(IApplicationThread caller,
16165            Intent intent, String resolvedType, IIntentReceiver resultTo,
16166            int resultCode, String resultData, Bundle map,
16167            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16168        enforceNotIsolatedCaller("broadcastIntent");
16169        synchronized(this) {
16170            intent = verifyBroadcastLocked(intent);
16171
16172            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16173            final int callingPid = Binder.getCallingPid();
16174            final int callingUid = Binder.getCallingUid();
16175            final long origId = Binder.clearCallingIdentity();
16176            int res = broadcastIntentLocked(callerApp,
16177                    callerApp != null ? callerApp.info.packageName : null,
16178                    intent, resolvedType, resultTo,
16179                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16180                    callingPid, callingUid, userId);
16181            Binder.restoreCallingIdentity(origId);
16182            return res;
16183        }
16184    }
16185
16186    int broadcastIntentInPackage(String packageName, int uid,
16187            Intent intent, String resolvedType, IIntentReceiver resultTo,
16188            int resultCode, String resultData, Bundle map,
16189            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16190        synchronized(this) {
16191            intent = verifyBroadcastLocked(intent);
16192
16193            final long origId = Binder.clearCallingIdentity();
16194            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16195                    resultTo, resultCode, resultData, map, requiredPermission,
16196                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16197            Binder.restoreCallingIdentity(origId);
16198            return res;
16199        }
16200    }
16201
16202    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16203        // Refuse possible leaked file descriptors
16204        if (intent != null && intent.hasFileDescriptors() == true) {
16205            throw new IllegalArgumentException("File descriptors passed in Intent");
16206        }
16207
16208        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16209                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16210
16211        synchronized(this) {
16212            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16213                    != PackageManager.PERMISSION_GRANTED) {
16214                String msg = "Permission Denial: unbroadcastIntent() from pid="
16215                        + Binder.getCallingPid()
16216                        + ", uid=" + Binder.getCallingUid()
16217                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16218                Slog.w(TAG, msg);
16219                throw new SecurityException(msg);
16220            }
16221            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16222            if (stickies != null) {
16223                ArrayList<Intent> list = stickies.get(intent.getAction());
16224                if (list != null) {
16225                    int N = list.size();
16226                    int i;
16227                    for (i=0; i<N; i++) {
16228                        if (intent.filterEquals(list.get(i))) {
16229                            list.remove(i);
16230                            break;
16231                        }
16232                    }
16233                    if (list.size() <= 0) {
16234                        stickies.remove(intent.getAction());
16235                    }
16236                }
16237                if (stickies.size() <= 0) {
16238                    mStickyBroadcasts.remove(userId);
16239                }
16240            }
16241        }
16242    }
16243
16244    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16245            String resultData, Bundle resultExtras, boolean resultAbort) {
16246        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16247        if (r == null) {
16248            Slog.w(TAG, "finishReceiver called but not found on queue");
16249            return false;
16250        }
16251
16252        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16253    }
16254
16255    void backgroundServicesFinishedLocked(int userId) {
16256        for (BroadcastQueue queue : mBroadcastQueues) {
16257            queue.backgroundServicesFinishedLocked(userId);
16258        }
16259    }
16260
16261    public void finishReceiver(IBinder who, int resultCode, String resultData,
16262            Bundle resultExtras, boolean resultAbort) {
16263        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16264
16265        // Refuse possible leaked file descriptors
16266        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16267            throw new IllegalArgumentException("File descriptors passed in Bundle");
16268        }
16269
16270        final long origId = Binder.clearCallingIdentity();
16271        try {
16272            boolean doNext = false;
16273            BroadcastRecord r;
16274
16275            synchronized(this) {
16276                r = broadcastRecordForReceiverLocked(who);
16277                if (r != null) {
16278                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16279                        resultData, resultExtras, resultAbort, true);
16280                }
16281            }
16282
16283            if (doNext) {
16284                r.queue.processNextBroadcast(false);
16285            }
16286            trimApplications();
16287        } finally {
16288            Binder.restoreCallingIdentity(origId);
16289        }
16290    }
16291
16292    // =========================================================
16293    // INSTRUMENTATION
16294    // =========================================================
16295
16296    public boolean startInstrumentation(ComponentName className,
16297            String profileFile, int flags, Bundle arguments,
16298            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16299            int userId, String abiOverride) {
16300        enforceNotIsolatedCaller("startInstrumentation");
16301        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16302                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16303        // Refuse possible leaked file descriptors
16304        if (arguments != null && arguments.hasFileDescriptors()) {
16305            throw new IllegalArgumentException("File descriptors passed in Bundle");
16306        }
16307
16308        synchronized(this) {
16309            InstrumentationInfo ii = null;
16310            ApplicationInfo ai = null;
16311            try {
16312                ii = mContext.getPackageManager().getInstrumentationInfo(
16313                    className, STOCK_PM_FLAGS);
16314                ai = AppGlobals.getPackageManager().getApplicationInfo(
16315                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16316            } catch (PackageManager.NameNotFoundException e) {
16317            } catch (RemoteException e) {
16318            }
16319            if (ii == null) {
16320                reportStartInstrumentationFailure(watcher, className,
16321                        "Unable to find instrumentation info for: " + className);
16322                return false;
16323            }
16324            if (ai == null) {
16325                reportStartInstrumentationFailure(watcher, className,
16326                        "Unable to find instrumentation target package: " + ii.targetPackage);
16327                return false;
16328            }
16329
16330            int match = mContext.getPackageManager().checkSignatures(
16331                    ii.targetPackage, ii.packageName);
16332            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16333                String msg = "Permission Denial: starting instrumentation "
16334                        + className + " from pid="
16335                        + Binder.getCallingPid()
16336                        + ", uid=" + Binder.getCallingPid()
16337                        + " not allowed because package " + ii.packageName
16338                        + " does not have a signature matching the target "
16339                        + ii.targetPackage;
16340                reportStartInstrumentationFailure(watcher, className, msg);
16341                throw new SecurityException(msg);
16342            }
16343
16344            final long origId = Binder.clearCallingIdentity();
16345            // Instrumentation can kill and relaunch even persistent processes
16346            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16347                    "start instr");
16348            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16349            app.instrumentationClass = className;
16350            app.instrumentationInfo = ai;
16351            app.instrumentationProfileFile = profileFile;
16352            app.instrumentationArguments = arguments;
16353            app.instrumentationWatcher = watcher;
16354            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16355            app.instrumentationResultClass = className;
16356            Binder.restoreCallingIdentity(origId);
16357        }
16358
16359        return true;
16360    }
16361
16362    /**
16363     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16364     * error to the logs, but if somebody is watching, send the report there too.  This enables
16365     * the "am" command to report errors with more information.
16366     *
16367     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16368     * @param cn The component name of the instrumentation.
16369     * @param report The error report.
16370     */
16371    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16372            ComponentName cn, String report) {
16373        Slog.w(TAG, report);
16374        try {
16375            if (watcher != null) {
16376                Bundle results = new Bundle();
16377                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16378                results.putString("Error", report);
16379                watcher.instrumentationStatus(cn, -1, results);
16380            }
16381        } catch (RemoteException e) {
16382            Slog.w(TAG, e);
16383        }
16384    }
16385
16386    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16387        if (app.instrumentationWatcher != null) {
16388            try {
16389                // NOTE:  IInstrumentationWatcher *must* be oneway here
16390                app.instrumentationWatcher.instrumentationFinished(
16391                    app.instrumentationClass,
16392                    resultCode,
16393                    results);
16394            } catch (RemoteException e) {
16395            }
16396        }
16397        if (app.instrumentationUiAutomationConnection != null) {
16398            try {
16399                app.instrumentationUiAutomationConnection.shutdown();
16400            } catch (RemoteException re) {
16401                /* ignore */
16402            }
16403            // Only a UiAutomation can set this flag and now that
16404            // it is finished we make sure it is reset to its default.
16405            mUserIsMonkey = false;
16406        }
16407        app.instrumentationWatcher = null;
16408        app.instrumentationUiAutomationConnection = null;
16409        app.instrumentationClass = null;
16410        app.instrumentationInfo = null;
16411        app.instrumentationProfileFile = null;
16412        app.instrumentationArguments = null;
16413
16414        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16415                "finished inst");
16416    }
16417
16418    public void finishInstrumentation(IApplicationThread target,
16419            int resultCode, Bundle results) {
16420        int userId = UserHandle.getCallingUserId();
16421        // Refuse possible leaked file descriptors
16422        if (results != null && results.hasFileDescriptors()) {
16423            throw new IllegalArgumentException("File descriptors passed in Intent");
16424        }
16425
16426        synchronized(this) {
16427            ProcessRecord app = getRecordForAppLocked(target);
16428            if (app == null) {
16429                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16430                return;
16431            }
16432            final long origId = Binder.clearCallingIdentity();
16433            finishInstrumentationLocked(app, resultCode, results);
16434            Binder.restoreCallingIdentity(origId);
16435        }
16436    }
16437
16438    // =========================================================
16439    // CONFIGURATION
16440    // =========================================================
16441
16442    public ConfigurationInfo getDeviceConfigurationInfo() {
16443        ConfigurationInfo config = new ConfigurationInfo();
16444        synchronized (this) {
16445            config.reqTouchScreen = mConfiguration.touchscreen;
16446            config.reqKeyboardType = mConfiguration.keyboard;
16447            config.reqNavigation = mConfiguration.navigation;
16448            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16449                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16450                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16451            }
16452            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16453                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16454                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16455            }
16456            config.reqGlEsVersion = GL_ES_VERSION;
16457        }
16458        return config;
16459    }
16460
16461    ActivityStack getFocusedStack() {
16462        return mStackSupervisor.getFocusedStack();
16463    }
16464
16465    public Configuration getConfiguration() {
16466        Configuration ci;
16467        synchronized(this) {
16468            ci = new Configuration(mConfiguration);
16469        }
16470        return ci;
16471    }
16472
16473    public void updatePersistentConfiguration(Configuration values) {
16474        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16475                "updateConfiguration()");
16476        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16477                "updateConfiguration()");
16478        if (values == null) {
16479            throw new NullPointerException("Configuration must not be null");
16480        }
16481
16482        synchronized(this) {
16483            final long origId = Binder.clearCallingIdentity();
16484            updateConfigurationLocked(values, null, true, false);
16485            Binder.restoreCallingIdentity(origId);
16486        }
16487    }
16488
16489    public void updateConfiguration(Configuration values) {
16490        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16491                "updateConfiguration()");
16492
16493        synchronized(this) {
16494            if (values == null && mWindowManager != null) {
16495                // sentinel: fetch the current configuration from the window manager
16496                values = mWindowManager.computeNewConfiguration();
16497            }
16498
16499            if (mWindowManager != null) {
16500                mProcessList.applyDisplaySize(mWindowManager);
16501            }
16502
16503            final long origId = Binder.clearCallingIdentity();
16504            if (values != null) {
16505                Settings.System.clearConfiguration(values);
16506            }
16507            updateConfigurationLocked(values, null, false, false);
16508            Binder.restoreCallingIdentity(origId);
16509        }
16510    }
16511
16512    /**
16513     * Do either or both things: (1) change the current configuration, and (2)
16514     * make sure the given activity is running with the (now) current
16515     * configuration.  Returns true if the activity has been left running, or
16516     * false if <var>starting</var> is being destroyed to match the new
16517     * configuration.
16518     * @param persistent TODO
16519     */
16520    boolean updateConfigurationLocked(Configuration values,
16521            ActivityRecord starting, boolean persistent, boolean initLocale) {
16522        int changes = 0;
16523
16524        if (values != null) {
16525            Configuration newConfig = new Configuration(mConfiguration);
16526            changes = newConfig.updateFrom(values);
16527            if (changes != 0) {
16528                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16529                    Slog.i(TAG, "Updating configuration to: " + values);
16530                }
16531
16532                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16533
16534                if (values.locale != null && !initLocale) {
16535                    saveLocaleLocked(values.locale,
16536                                     !values.locale.equals(mConfiguration.locale),
16537                                     values.userSetLocale);
16538                }
16539
16540                mConfigurationSeq++;
16541                if (mConfigurationSeq <= 0) {
16542                    mConfigurationSeq = 1;
16543                }
16544                newConfig.seq = mConfigurationSeq;
16545                mConfiguration = newConfig;
16546                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16547                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16548                //mUsageStatsService.noteStartConfig(newConfig);
16549
16550                final Configuration configCopy = new Configuration(mConfiguration);
16551
16552                // TODO: If our config changes, should we auto dismiss any currently
16553                // showing dialogs?
16554                mShowDialogs = shouldShowDialogs(newConfig);
16555
16556                AttributeCache ac = AttributeCache.instance();
16557                if (ac != null) {
16558                    ac.updateConfiguration(configCopy);
16559                }
16560
16561                // Make sure all resources in our process are updated
16562                // right now, so that anyone who is going to retrieve
16563                // resource values after we return will be sure to get
16564                // the new ones.  This is especially important during
16565                // boot, where the first config change needs to guarantee
16566                // all resources have that config before following boot
16567                // code is executed.
16568                mSystemThread.applyConfigurationToResources(configCopy);
16569
16570                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16571                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16572                    msg.obj = new Configuration(configCopy);
16573                    mHandler.sendMessage(msg);
16574                }
16575
16576                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16577                    ProcessRecord app = mLruProcesses.get(i);
16578                    try {
16579                        if (app.thread != null) {
16580                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16581                                    + app.processName + " new config " + mConfiguration);
16582                            app.thread.scheduleConfigurationChanged(configCopy);
16583                        }
16584                    } catch (Exception e) {
16585                    }
16586                }
16587                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16588                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16589                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16590                        | Intent.FLAG_RECEIVER_FOREGROUND);
16591                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16592                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16593                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16594                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16595                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16596                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16597                    broadcastIntentLocked(null, null, intent,
16598                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16599                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16600                }
16601            }
16602        }
16603
16604        boolean kept = true;
16605        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16606        // mainStack is null during startup.
16607        if (mainStack != null) {
16608            if (changes != 0 && starting == null) {
16609                // If the configuration changed, and the caller is not already
16610                // in the process of starting an activity, then find the top
16611                // activity to check if its configuration needs to change.
16612                starting = mainStack.topRunningActivityLocked(null);
16613            }
16614
16615            if (starting != null) {
16616                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16617                // And we need to make sure at this point that all other activities
16618                // are made visible with the correct configuration.
16619                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16620            }
16621        }
16622
16623        if (values != null && mWindowManager != null) {
16624            mWindowManager.setNewConfiguration(mConfiguration);
16625        }
16626
16627        return kept;
16628    }
16629
16630    /**
16631     * Decide based on the configuration whether we should shouw the ANR,
16632     * crash, etc dialogs.  The idea is that if there is no affordnace to
16633     * press the on-screen buttons, we shouldn't show the dialog.
16634     *
16635     * A thought: SystemUI might also want to get told about this, the Power
16636     * dialog / global actions also might want different behaviors.
16637     */
16638    private static final boolean shouldShowDialogs(Configuration config) {
16639        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16640                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16641    }
16642
16643    /**
16644     * Save the locale.  You must be inside a synchronized (this) block.
16645     */
16646    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16647        if(isDiff) {
16648            SystemProperties.set("user.language", l.getLanguage());
16649            SystemProperties.set("user.region", l.getCountry());
16650        }
16651
16652        if(isPersist) {
16653            SystemProperties.set("persist.sys.language", l.getLanguage());
16654            SystemProperties.set("persist.sys.country", l.getCountry());
16655            SystemProperties.set("persist.sys.localevar", l.getVariant());
16656
16657            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16658        }
16659    }
16660
16661    @Override
16662    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16663        synchronized (this) {
16664            ActivityRecord srec = ActivityRecord.forToken(token);
16665            if (srec.task != null && srec.task.stack != null) {
16666                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16667            }
16668        }
16669        return false;
16670    }
16671
16672    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16673            Intent resultData) {
16674
16675        synchronized (this) {
16676            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16677            if (stack != null) {
16678                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16679            }
16680            return false;
16681        }
16682    }
16683
16684    public int getLaunchedFromUid(IBinder activityToken) {
16685        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16686        if (srec == null) {
16687            return -1;
16688        }
16689        return srec.launchedFromUid;
16690    }
16691
16692    public String getLaunchedFromPackage(IBinder activityToken) {
16693        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16694        if (srec == null) {
16695            return null;
16696        }
16697        return srec.launchedFromPackage;
16698    }
16699
16700    // =========================================================
16701    // LIFETIME MANAGEMENT
16702    // =========================================================
16703
16704    // Returns which broadcast queue the app is the current [or imminent] receiver
16705    // on, or 'null' if the app is not an active broadcast recipient.
16706    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16707        BroadcastRecord r = app.curReceiver;
16708        if (r != null) {
16709            return r.queue;
16710        }
16711
16712        // It's not the current receiver, but it might be starting up to become one
16713        synchronized (this) {
16714            for (BroadcastQueue queue : mBroadcastQueues) {
16715                r = queue.mPendingBroadcast;
16716                if (r != null && r.curApp == app) {
16717                    // found it; report which queue it's in
16718                    return queue;
16719                }
16720            }
16721        }
16722
16723        return null;
16724    }
16725
16726    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16727            boolean doingAll, long now) {
16728        if (mAdjSeq == app.adjSeq) {
16729            // This adjustment has already been computed.
16730            return app.curRawAdj;
16731        }
16732
16733        if (app.thread == null) {
16734            app.adjSeq = mAdjSeq;
16735            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16736            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16737            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16738        }
16739
16740        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16741        app.adjSource = null;
16742        app.adjTarget = null;
16743        app.empty = false;
16744        app.cached = false;
16745
16746        final int activitiesSize = app.activities.size();
16747
16748        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16749            // The max adjustment doesn't allow this app to be anything
16750            // below foreground, so it is not worth doing work for it.
16751            app.adjType = "fixed";
16752            app.adjSeq = mAdjSeq;
16753            app.curRawAdj = app.maxAdj;
16754            app.foregroundActivities = false;
16755            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16756            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16757            // System processes can do UI, and when they do we want to have
16758            // them trim their memory after the user leaves the UI.  To
16759            // facilitate this, here we need to determine whether or not it
16760            // is currently showing UI.
16761            app.systemNoUi = true;
16762            if (app == TOP_APP) {
16763                app.systemNoUi = false;
16764            } else if (activitiesSize > 0) {
16765                for (int j = 0; j < activitiesSize; j++) {
16766                    final ActivityRecord r = app.activities.get(j);
16767                    if (r.visible) {
16768                        app.systemNoUi = false;
16769                    }
16770                }
16771            }
16772            if (!app.systemNoUi) {
16773                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16774            }
16775            return (app.curAdj=app.maxAdj);
16776        }
16777
16778        app.systemNoUi = false;
16779
16780        // Determine the importance of the process, starting with most
16781        // important to least, and assign an appropriate OOM adjustment.
16782        int adj;
16783        int schedGroup;
16784        int procState;
16785        boolean foregroundActivities = false;
16786        BroadcastQueue queue;
16787        if (app == TOP_APP) {
16788            // The last app on the list is the foreground app.
16789            adj = ProcessList.FOREGROUND_APP_ADJ;
16790            schedGroup = Process.THREAD_GROUP_DEFAULT;
16791            app.adjType = "top-activity";
16792            foregroundActivities = true;
16793            procState = ActivityManager.PROCESS_STATE_TOP;
16794        } else if (app.instrumentationClass != null) {
16795            // Don't want to kill running instrumentation.
16796            adj = ProcessList.FOREGROUND_APP_ADJ;
16797            schedGroup = Process.THREAD_GROUP_DEFAULT;
16798            app.adjType = "instrumentation";
16799            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16800        } else if ((queue = isReceivingBroadcast(app)) != null) {
16801            // An app that is currently receiving a broadcast also
16802            // counts as being in the foreground for OOM killer purposes.
16803            // It's placed in a sched group based on the nature of the
16804            // broadcast as reflected by which queue it's active in.
16805            adj = ProcessList.FOREGROUND_APP_ADJ;
16806            schedGroup = (queue == mFgBroadcastQueue)
16807                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16808            app.adjType = "broadcast";
16809            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16810        } else if (app.executingServices.size() > 0) {
16811            // An app that is currently executing a service callback also
16812            // counts as being in the foreground.
16813            adj = ProcessList.FOREGROUND_APP_ADJ;
16814            schedGroup = app.execServicesFg ?
16815                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16816            app.adjType = "exec-service";
16817            procState = ActivityManager.PROCESS_STATE_SERVICE;
16818            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16819        } else {
16820            // As far as we know the process is empty.  We may change our mind later.
16821            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16822            // At this point we don't actually know the adjustment.  Use the cached adj
16823            // value that the caller wants us to.
16824            adj = cachedAdj;
16825            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16826            app.cached = true;
16827            app.empty = true;
16828            app.adjType = "cch-empty";
16829        }
16830
16831        // Examine all activities if not already foreground.
16832        if (!foregroundActivities && activitiesSize > 0) {
16833            for (int j = 0; j < activitiesSize; j++) {
16834                final ActivityRecord r = app.activities.get(j);
16835                if (r.app != app) {
16836                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16837                            + app + "?!?");
16838                    continue;
16839                }
16840                if (r.visible) {
16841                    // App has a visible activity; only upgrade adjustment.
16842                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16843                        adj = ProcessList.VISIBLE_APP_ADJ;
16844                        app.adjType = "visible";
16845                    }
16846                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16847                        procState = ActivityManager.PROCESS_STATE_TOP;
16848                    }
16849                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16850                    app.cached = false;
16851                    app.empty = false;
16852                    foregroundActivities = true;
16853                    break;
16854                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16855                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16856                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16857                        app.adjType = "pausing";
16858                    }
16859                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16860                        procState = ActivityManager.PROCESS_STATE_TOP;
16861                    }
16862                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16863                    app.cached = false;
16864                    app.empty = false;
16865                    foregroundActivities = true;
16866                } else if (r.state == ActivityState.STOPPING) {
16867                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16868                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16869                        app.adjType = "stopping";
16870                    }
16871                    // For the process state, we will at this point consider the
16872                    // process to be cached.  It will be cached either as an activity
16873                    // or empty depending on whether the activity is finishing.  We do
16874                    // this so that we can treat the process as cached for purposes of
16875                    // memory trimming (determing current memory level, trim command to
16876                    // send to process) since there can be an arbitrary number of stopping
16877                    // processes and they should soon all go into the cached state.
16878                    if (!r.finishing) {
16879                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16880                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16881                        }
16882                    }
16883                    app.cached = false;
16884                    app.empty = false;
16885                    foregroundActivities = true;
16886                } else {
16887                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16888                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16889                        app.adjType = "cch-act";
16890                    }
16891                }
16892            }
16893        }
16894
16895        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16896            if (app.foregroundServices) {
16897                // The user is aware of this app, so make it visible.
16898                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16899                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16900                app.cached = false;
16901                app.adjType = "fg-service";
16902                schedGroup = Process.THREAD_GROUP_DEFAULT;
16903            } else if (app.forcingToForeground != null) {
16904                // The user is aware of this app, so make it visible.
16905                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16906                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16907                app.cached = false;
16908                app.adjType = "force-fg";
16909                app.adjSource = app.forcingToForeground;
16910                schedGroup = Process.THREAD_GROUP_DEFAULT;
16911            }
16912        }
16913
16914        if (app == mHeavyWeightProcess) {
16915            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16916                // We don't want to kill the current heavy-weight process.
16917                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16918                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16919                app.cached = false;
16920                app.adjType = "heavy";
16921            }
16922            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16923                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16924            }
16925        }
16926
16927        if (app == mHomeProcess) {
16928            if (adj > ProcessList.HOME_APP_ADJ) {
16929                // This process is hosting what we currently consider to be the
16930                // home app, so we don't want to let it go into the background.
16931                adj = ProcessList.HOME_APP_ADJ;
16932                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16933                app.cached = false;
16934                app.adjType = "home";
16935            }
16936            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16937                procState = ActivityManager.PROCESS_STATE_HOME;
16938            }
16939        }
16940
16941        if (app == mPreviousProcess && app.activities.size() > 0) {
16942            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16943                // This was the previous process that showed UI to the user.
16944                // We want to try to keep it around more aggressively, to give
16945                // a good experience around switching between two apps.
16946                adj = ProcessList.PREVIOUS_APP_ADJ;
16947                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16948                app.cached = false;
16949                app.adjType = "previous";
16950            }
16951            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16952                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16953            }
16954        }
16955
16956        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16957                + " reason=" + app.adjType);
16958
16959        // By default, we use the computed adjustment.  It may be changed if
16960        // there are applications dependent on our services or providers, but
16961        // this gives us a baseline and makes sure we don't get into an
16962        // infinite recursion.
16963        app.adjSeq = mAdjSeq;
16964        app.curRawAdj = adj;
16965        app.hasStartedServices = false;
16966
16967        if (mBackupTarget != null && app == mBackupTarget.app) {
16968            // If possible we want to avoid killing apps while they're being backed up
16969            if (adj > ProcessList.BACKUP_APP_ADJ) {
16970                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16971                adj = ProcessList.BACKUP_APP_ADJ;
16972                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16973                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16974                }
16975                app.adjType = "backup";
16976                app.cached = false;
16977            }
16978            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16979                procState = ActivityManager.PROCESS_STATE_BACKUP;
16980            }
16981        }
16982
16983        boolean mayBeTop = false;
16984
16985        for (int is = app.services.size()-1;
16986                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16987                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16988                        || procState > ActivityManager.PROCESS_STATE_TOP);
16989                is--) {
16990            ServiceRecord s = app.services.valueAt(is);
16991            if (s.startRequested) {
16992                app.hasStartedServices = true;
16993                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16994                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16995                }
16996                if (app.hasShownUi && app != mHomeProcess) {
16997                    // If this process has shown some UI, let it immediately
16998                    // go to the LRU list because it may be pretty heavy with
16999                    // UI stuff.  We'll tag it with a label just to help
17000                    // debug and understand what is going on.
17001                    if (adj > ProcessList.SERVICE_ADJ) {
17002                        app.adjType = "cch-started-ui-services";
17003                    }
17004                } else {
17005                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17006                        // This service has seen some activity within
17007                        // recent memory, so we will keep its process ahead
17008                        // of the background processes.
17009                        if (adj > ProcessList.SERVICE_ADJ) {
17010                            adj = ProcessList.SERVICE_ADJ;
17011                            app.adjType = "started-services";
17012                            app.cached = false;
17013                        }
17014                    }
17015                    // If we have let the service slide into the background
17016                    // state, still have some text describing what it is doing
17017                    // even though the service no longer has an impact.
17018                    if (adj > ProcessList.SERVICE_ADJ) {
17019                        app.adjType = "cch-started-services";
17020                    }
17021                }
17022            }
17023            for (int conni = s.connections.size()-1;
17024                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17025                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17026                            || procState > ActivityManager.PROCESS_STATE_TOP);
17027                    conni--) {
17028                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17029                for (int i = 0;
17030                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17031                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17032                                || procState > ActivityManager.PROCESS_STATE_TOP);
17033                        i++) {
17034                    // XXX should compute this based on the max of
17035                    // all connected clients.
17036                    ConnectionRecord cr = clist.get(i);
17037                    if (cr.binding.client == app) {
17038                        // Binding to ourself is not interesting.
17039                        continue;
17040                    }
17041                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17042                        ProcessRecord client = cr.binding.client;
17043                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17044                                TOP_APP, doingAll, now);
17045                        int clientProcState = client.curProcState;
17046                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17047                            // If the other app is cached for any reason, for purposes here
17048                            // we are going to consider it empty.  The specific cached state
17049                            // doesn't propagate except under certain conditions.
17050                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17051                        }
17052                        String adjType = null;
17053                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17054                            // Not doing bind OOM management, so treat
17055                            // this guy more like a started service.
17056                            if (app.hasShownUi && app != mHomeProcess) {
17057                                // If this process has shown some UI, let it immediately
17058                                // go to the LRU list because it may be pretty heavy with
17059                                // UI stuff.  We'll tag it with a label just to help
17060                                // debug and understand what is going on.
17061                                if (adj > clientAdj) {
17062                                    adjType = "cch-bound-ui-services";
17063                                }
17064                                app.cached = false;
17065                                clientAdj = adj;
17066                                clientProcState = procState;
17067                            } else {
17068                                if (now >= (s.lastActivity
17069                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17070                                    // This service has not seen activity within
17071                                    // recent memory, so allow it to drop to the
17072                                    // LRU list if there is no other reason to keep
17073                                    // it around.  We'll also tag it with a label just
17074                                    // to help debug and undertand what is going on.
17075                                    if (adj > clientAdj) {
17076                                        adjType = "cch-bound-services";
17077                                    }
17078                                    clientAdj = adj;
17079                                }
17080                            }
17081                        }
17082                        if (adj > clientAdj) {
17083                            // If this process has recently shown UI, and
17084                            // the process that is binding to it is less
17085                            // important than being visible, then we don't
17086                            // care about the binding as much as we care
17087                            // about letting this process get into the LRU
17088                            // list to be killed and restarted if needed for
17089                            // memory.
17090                            if (app.hasShownUi && app != mHomeProcess
17091                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17092                                adjType = "cch-bound-ui-services";
17093                            } else {
17094                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17095                                        |Context.BIND_IMPORTANT)) != 0) {
17096                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17097                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17098                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17099                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17100                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17101                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17102                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17103                                    adj = clientAdj;
17104                                } else {
17105                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17106                                        adj = ProcessList.VISIBLE_APP_ADJ;
17107                                    }
17108                                }
17109                                if (!client.cached) {
17110                                    app.cached = false;
17111                                }
17112                                adjType = "service";
17113                            }
17114                        }
17115                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17116                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17117                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17118                            }
17119                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17120                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17121                                    // Special handling of clients who are in the top state.
17122                                    // We *may* want to consider this process to be in the
17123                                    // top state as well, but only if there is not another
17124                                    // reason for it to be running.  Being on the top is a
17125                                    // special state, meaning you are specifically running
17126                                    // for the current top app.  If the process is already
17127                                    // running in the background for some other reason, it
17128                                    // is more important to continue considering it to be
17129                                    // in the background state.
17130                                    mayBeTop = true;
17131                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17132                                } else {
17133                                    // Special handling for above-top states (persistent
17134                                    // processes).  These should not bring the current process
17135                                    // into the top state, since they are not on top.  Instead
17136                                    // give them the best state after that.
17137                                    clientProcState =
17138                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17139                                }
17140                            }
17141                        } else {
17142                            if (clientProcState <
17143                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17144                                clientProcState =
17145                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17146                            }
17147                        }
17148                        if (procState > clientProcState) {
17149                            procState = clientProcState;
17150                        }
17151                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17152                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17153                            app.pendingUiClean = true;
17154                        }
17155                        if (adjType != null) {
17156                            app.adjType = adjType;
17157                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17158                                    .REASON_SERVICE_IN_USE;
17159                            app.adjSource = cr.binding.client;
17160                            app.adjSourceProcState = clientProcState;
17161                            app.adjTarget = s.name;
17162                        }
17163                    }
17164                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17165                        app.treatLikeActivity = true;
17166                    }
17167                    final ActivityRecord a = cr.activity;
17168                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17169                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17170                                (a.visible || a.state == ActivityState.RESUMED
17171                                 || a.state == ActivityState.PAUSING)) {
17172                            adj = ProcessList.FOREGROUND_APP_ADJ;
17173                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17174                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17175                            }
17176                            app.cached = false;
17177                            app.adjType = "service";
17178                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17179                                    .REASON_SERVICE_IN_USE;
17180                            app.adjSource = a;
17181                            app.adjSourceProcState = procState;
17182                            app.adjTarget = s.name;
17183                        }
17184                    }
17185                }
17186            }
17187        }
17188
17189        for (int provi = app.pubProviders.size()-1;
17190                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17191                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17192                        || procState > ActivityManager.PROCESS_STATE_TOP);
17193                provi--) {
17194            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17195            for (int i = cpr.connections.size()-1;
17196                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17197                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17198                            || procState > ActivityManager.PROCESS_STATE_TOP);
17199                    i--) {
17200                ContentProviderConnection conn = cpr.connections.get(i);
17201                ProcessRecord client = conn.client;
17202                if (client == app) {
17203                    // Being our own client is not interesting.
17204                    continue;
17205                }
17206                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17207                int clientProcState = client.curProcState;
17208                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17209                    // If the other app is cached for any reason, for purposes here
17210                    // we are going to consider it empty.
17211                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17212                }
17213                if (adj > clientAdj) {
17214                    if (app.hasShownUi && app != mHomeProcess
17215                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17216                        app.adjType = "cch-ui-provider";
17217                    } else {
17218                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17219                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17220                        app.adjType = "provider";
17221                    }
17222                    app.cached &= client.cached;
17223                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17224                            .REASON_PROVIDER_IN_USE;
17225                    app.adjSource = client;
17226                    app.adjSourceProcState = clientProcState;
17227                    app.adjTarget = cpr.name;
17228                }
17229                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17230                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17231                        // Special handling of clients who are in the top state.
17232                        // We *may* want to consider this process to be in the
17233                        // top state as well, but only if there is not another
17234                        // reason for it to be running.  Being on the top is a
17235                        // special state, meaning you are specifically running
17236                        // for the current top app.  If the process is already
17237                        // running in the background for some other reason, it
17238                        // is more important to continue considering it to be
17239                        // in the background state.
17240                        mayBeTop = true;
17241                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17242                    } else {
17243                        // Special handling for above-top states (persistent
17244                        // processes).  These should not bring the current process
17245                        // into the top state, since they are not on top.  Instead
17246                        // give them the best state after that.
17247                        clientProcState =
17248                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17249                    }
17250                }
17251                if (procState > clientProcState) {
17252                    procState = clientProcState;
17253                }
17254                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17255                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17256                }
17257            }
17258            // If the provider has external (non-framework) process
17259            // dependencies, ensure that its adjustment is at least
17260            // FOREGROUND_APP_ADJ.
17261            if (cpr.hasExternalProcessHandles()) {
17262                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17263                    adj = ProcessList.FOREGROUND_APP_ADJ;
17264                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17265                    app.cached = false;
17266                    app.adjType = "provider";
17267                    app.adjTarget = cpr.name;
17268                }
17269                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17270                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17271                }
17272            }
17273        }
17274
17275        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17276            // A client of one of our services or providers is in the top state.  We
17277            // *may* want to be in the top state, but not if we are already running in
17278            // the background for some other reason.  For the decision here, we are going
17279            // to pick out a few specific states that we want to remain in when a client
17280            // is top (states that tend to be longer-term) and otherwise allow it to go
17281            // to the top state.
17282            switch (procState) {
17283                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17284                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17285                case ActivityManager.PROCESS_STATE_SERVICE:
17286                    // These all are longer-term states, so pull them up to the top
17287                    // of the background states, but not all the way to the top state.
17288                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17289                    break;
17290                default:
17291                    // Otherwise, top is a better choice, so take it.
17292                    procState = ActivityManager.PROCESS_STATE_TOP;
17293                    break;
17294            }
17295        }
17296
17297        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17298            if (app.hasClientActivities) {
17299                // This is a cached process, but with client activities.  Mark it so.
17300                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17301                app.adjType = "cch-client-act";
17302            } else if (app.treatLikeActivity) {
17303                // This is a cached process, but somebody wants us to treat it like it has
17304                // an activity, okay!
17305                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17306                app.adjType = "cch-as-act";
17307            }
17308        }
17309
17310        if (adj == ProcessList.SERVICE_ADJ) {
17311            if (doingAll) {
17312                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17313                mNewNumServiceProcs++;
17314                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17315                if (!app.serviceb) {
17316                    // This service isn't far enough down on the LRU list to
17317                    // normally be a B service, but if we are low on RAM and it
17318                    // is large we want to force it down since we would prefer to
17319                    // keep launcher over it.
17320                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17321                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17322                        app.serviceHighRam = true;
17323                        app.serviceb = true;
17324                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17325                    } else {
17326                        mNewNumAServiceProcs++;
17327                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17328                    }
17329                } else {
17330                    app.serviceHighRam = false;
17331                }
17332            }
17333            if (app.serviceb) {
17334                adj = ProcessList.SERVICE_B_ADJ;
17335            }
17336        }
17337
17338        app.curRawAdj = adj;
17339
17340        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17341        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17342        if (adj > app.maxAdj) {
17343            adj = app.maxAdj;
17344            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17345                schedGroup = Process.THREAD_GROUP_DEFAULT;
17346            }
17347        }
17348
17349        // Do final modification to adj.  Everything we do between here and applying
17350        // the final setAdj must be done in this function, because we will also use
17351        // it when computing the final cached adj later.  Note that we don't need to
17352        // worry about this for max adj above, since max adj will always be used to
17353        // keep it out of the cached vaues.
17354        app.curAdj = app.modifyRawOomAdj(adj);
17355        app.curSchedGroup = schedGroup;
17356        app.curProcState = procState;
17357        app.foregroundActivities = foregroundActivities;
17358
17359        return app.curRawAdj;
17360    }
17361
17362    /**
17363     * Record new PSS sample for a process.
17364     */
17365    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17366        proc.lastPssTime = now;
17367        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17368        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17369                + ": " + pss + " lastPss=" + proc.lastPss
17370                + " state=" + ProcessList.makeProcStateString(procState));
17371        if (proc.initialIdlePss == 0) {
17372            proc.initialIdlePss = pss;
17373        }
17374        proc.lastPss = pss;
17375        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17376            proc.lastCachedPss = pss;
17377        }
17378    }
17379
17380    /**
17381     * Schedule PSS collection of a process.
17382     */
17383    void requestPssLocked(ProcessRecord proc, int procState) {
17384        if (mPendingPssProcesses.contains(proc)) {
17385            return;
17386        }
17387        if (mPendingPssProcesses.size() == 0) {
17388            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17389        }
17390        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17391        proc.pssProcState = procState;
17392        mPendingPssProcesses.add(proc);
17393    }
17394
17395    /**
17396     * Schedule PSS collection of all processes.
17397     */
17398    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17399        if (!always) {
17400            if (now < (mLastFullPssTime +
17401                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17402                return;
17403            }
17404        }
17405        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17406        mLastFullPssTime = now;
17407        mFullPssPending = true;
17408        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17409        mPendingPssProcesses.clear();
17410        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17411            ProcessRecord app = mLruProcesses.get(i);
17412            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17413                app.pssProcState = app.setProcState;
17414                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17415                        mTestPssMode, isSleeping(), now);
17416                mPendingPssProcesses.add(app);
17417            }
17418        }
17419        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17420    }
17421
17422    public void setTestPssMode(boolean enabled) {
17423        synchronized (this) {
17424            mTestPssMode = enabled;
17425            if (enabled) {
17426                // Whenever we enable the mode, we want to take a snapshot all of current
17427                // process mem use.
17428                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17429            }
17430        }
17431    }
17432
17433    /**
17434     * Ask a given process to GC right now.
17435     */
17436    final void performAppGcLocked(ProcessRecord app) {
17437        try {
17438            app.lastRequestedGc = SystemClock.uptimeMillis();
17439            if (app.thread != null) {
17440                if (app.reportLowMemory) {
17441                    app.reportLowMemory = false;
17442                    app.thread.scheduleLowMemory();
17443                } else {
17444                    app.thread.processInBackground();
17445                }
17446            }
17447        } catch (Exception e) {
17448            // whatever.
17449        }
17450    }
17451
17452    /**
17453     * Returns true if things are idle enough to perform GCs.
17454     */
17455    private final boolean canGcNowLocked() {
17456        boolean processingBroadcasts = false;
17457        for (BroadcastQueue q : mBroadcastQueues) {
17458            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17459                processingBroadcasts = true;
17460            }
17461        }
17462        return !processingBroadcasts
17463                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17464    }
17465
17466    /**
17467     * Perform GCs on all processes that are waiting for it, but only
17468     * if things are idle.
17469     */
17470    final void performAppGcsLocked() {
17471        final int N = mProcessesToGc.size();
17472        if (N <= 0) {
17473            return;
17474        }
17475        if (canGcNowLocked()) {
17476            while (mProcessesToGc.size() > 0) {
17477                ProcessRecord proc = mProcessesToGc.remove(0);
17478                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17479                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17480                            <= SystemClock.uptimeMillis()) {
17481                        // To avoid spamming the system, we will GC processes one
17482                        // at a time, waiting a few seconds between each.
17483                        performAppGcLocked(proc);
17484                        scheduleAppGcsLocked();
17485                        return;
17486                    } else {
17487                        // It hasn't been long enough since we last GCed this
17488                        // process...  put it in the list to wait for its time.
17489                        addProcessToGcListLocked(proc);
17490                        break;
17491                    }
17492                }
17493            }
17494
17495            scheduleAppGcsLocked();
17496        }
17497    }
17498
17499    /**
17500     * If all looks good, perform GCs on all processes waiting for them.
17501     */
17502    final void performAppGcsIfAppropriateLocked() {
17503        if (canGcNowLocked()) {
17504            performAppGcsLocked();
17505            return;
17506        }
17507        // Still not idle, wait some more.
17508        scheduleAppGcsLocked();
17509    }
17510
17511    /**
17512     * Schedule the execution of all pending app GCs.
17513     */
17514    final void scheduleAppGcsLocked() {
17515        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17516
17517        if (mProcessesToGc.size() > 0) {
17518            // Schedule a GC for the time to the next process.
17519            ProcessRecord proc = mProcessesToGc.get(0);
17520            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17521
17522            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17523            long now = SystemClock.uptimeMillis();
17524            if (when < (now+GC_TIMEOUT)) {
17525                when = now + GC_TIMEOUT;
17526            }
17527            mHandler.sendMessageAtTime(msg, when);
17528        }
17529    }
17530
17531    /**
17532     * Add a process to the array of processes waiting to be GCed.  Keeps the
17533     * list in sorted order by the last GC time.  The process can't already be
17534     * on the list.
17535     */
17536    final void addProcessToGcListLocked(ProcessRecord proc) {
17537        boolean added = false;
17538        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17539            if (mProcessesToGc.get(i).lastRequestedGc <
17540                    proc.lastRequestedGc) {
17541                added = true;
17542                mProcessesToGc.add(i+1, proc);
17543                break;
17544            }
17545        }
17546        if (!added) {
17547            mProcessesToGc.add(0, proc);
17548        }
17549    }
17550
17551    /**
17552     * Set up to ask a process to GC itself.  This will either do it
17553     * immediately, or put it on the list of processes to gc the next
17554     * time things are idle.
17555     */
17556    final void scheduleAppGcLocked(ProcessRecord app) {
17557        long now = SystemClock.uptimeMillis();
17558        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17559            return;
17560        }
17561        if (!mProcessesToGc.contains(app)) {
17562            addProcessToGcListLocked(app);
17563            scheduleAppGcsLocked();
17564        }
17565    }
17566
17567    final void checkExcessivePowerUsageLocked(boolean doKills) {
17568        updateCpuStatsNow();
17569
17570        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17571        boolean doWakeKills = doKills;
17572        boolean doCpuKills = doKills;
17573        if (mLastPowerCheckRealtime == 0) {
17574            doWakeKills = false;
17575        }
17576        if (mLastPowerCheckUptime == 0) {
17577            doCpuKills = false;
17578        }
17579        if (stats.isScreenOn()) {
17580            doWakeKills = false;
17581        }
17582        final long curRealtime = SystemClock.elapsedRealtime();
17583        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17584        final long curUptime = SystemClock.uptimeMillis();
17585        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17586        mLastPowerCheckRealtime = curRealtime;
17587        mLastPowerCheckUptime = curUptime;
17588        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17589            doWakeKills = false;
17590        }
17591        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17592            doCpuKills = false;
17593        }
17594        int i = mLruProcesses.size();
17595        while (i > 0) {
17596            i--;
17597            ProcessRecord app = mLruProcesses.get(i);
17598            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17599                long wtime;
17600                synchronized (stats) {
17601                    wtime = stats.getProcessWakeTime(app.info.uid,
17602                            app.pid, curRealtime);
17603                }
17604                long wtimeUsed = wtime - app.lastWakeTime;
17605                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17606                if (DEBUG_POWER) {
17607                    StringBuilder sb = new StringBuilder(128);
17608                    sb.append("Wake for ");
17609                    app.toShortString(sb);
17610                    sb.append(": over ");
17611                    TimeUtils.formatDuration(realtimeSince, sb);
17612                    sb.append(" used ");
17613                    TimeUtils.formatDuration(wtimeUsed, sb);
17614                    sb.append(" (");
17615                    sb.append((wtimeUsed*100)/realtimeSince);
17616                    sb.append("%)");
17617                    Slog.i(TAG, sb.toString());
17618                    sb.setLength(0);
17619                    sb.append("CPU for ");
17620                    app.toShortString(sb);
17621                    sb.append(": over ");
17622                    TimeUtils.formatDuration(uptimeSince, sb);
17623                    sb.append(" used ");
17624                    TimeUtils.formatDuration(cputimeUsed, sb);
17625                    sb.append(" (");
17626                    sb.append((cputimeUsed*100)/uptimeSince);
17627                    sb.append("%)");
17628                    Slog.i(TAG, sb.toString());
17629                }
17630                // If a process has held a wake lock for more
17631                // than 50% of the time during this period,
17632                // that sounds bad.  Kill!
17633                if (doWakeKills && realtimeSince > 0
17634                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17635                    synchronized (stats) {
17636                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17637                                realtimeSince, wtimeUsed);
17638                    }
17639                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17640                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17641                } else if (doCpuKills && uptimeSince > 0
17642                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17643                    synchronized (stats) {
17644                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17645                                uptimeSince, cputimeUsed);
17646                    }
17647                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17648                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17649                } else {
17650                    app.lastWakeTime = wtime;
17651                    app.lastCpuTime = app.curCpuTime;
17652                }
17653            }
17654        }
17655    }
17656
17657    private final boolean applyOomAdjLocked(ProcessRecord app,
17658            ProcessRecord TOP_APP, boolean doingAll, long now) {
17659        boolean success = true;
17660
17661        if (app.curRawAdj != app.setRawAdj) {
17662            app.setRawAdj = app.curRawAdj;
17663        }
17664
17665        int changes = 0;
17666
17667        if (app.curAdj != app.setAdj) {
17668            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17669            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17670                TAG, "Set " + app.pid + " " + app.processName +
17671                " adj " + app.curAdj + ": " + app.adjType);
17672            app.setAdj = app.curAdj;
17673        }
17674
17675        if (app.setSchedGroup != app.curSchedGroup) {
17676            app.setSchedGroup = app.curSchedGroup;
17677            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17678                    "Setting process group of " + app.processName
17679                    + " to " + app.curSchedGroup);
17680            if (app.waitingToKill != null &&
17681                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17682                app.kill(app.waitingToKill, true);
17683                success = false;
17684            } else {
17685                if (true) {
17686                    long oldId = Binder.clearCallingIdentity();
17687                    try {
17688                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17689                    } catch (Exception e) {
17690                        Slog.w(TAG, "Failed setting process group of " + app.pid
17691                                + " to " + app.curSchedGroup);
17692                        e.printStackTrace();
17693                    } finally {
17694                        Binder.restoreCallingIdentity(oldId);
17695                    }
17696                } else {
17697                    if (app.thread != null) {
17698                        try {
17699                            app.thread.setSchedulingGroup(app.curSchedGroup);
17700                        } catch (RemoteException e) {
17701                        }
17702                    }
17703                }
17704                Process.setSwappiness(app.pid,
17705                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17706            }
17707        }
17708        if (app.repForegroundActivities != app.foregroundActivities) {
17709            app.repForegroundActivities = app.foregroundActivities;
17710            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17711        }
17712        if (app.repProcState != app.curProcState) {
17713            app.repProcState = app.curProcState;
17714            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17715            if (app.thread != null) {
17716                try {
17717                    if (false) {
17718                        //RuntimeException h = new RuntimeException("here");
17719                        Slog.i(TAG, "Sending new process state " + app.repProcState
17720                                + " to " + app /*, h*/);
17721                    }
17722                    app.thread.setProcessState(app.repProcState);
17723                } catch (RemoteException e) {
17724                }
17725            }
17726        }
17727        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17728                app.setProcState)) {
17729            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17730                // Experimental code to more aggressively collect pss while
17731                // running test...  the problem is that this tends to collect
17732                // the data right when a process is transitioning between process
17733                // states, which well tend to give noisy data.
17734                long start = SystemClock.uptimeMillis();
17735                long pss = Debug.getPss(app.pid, mTmpLong, null);
17736                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17737                mPendingPssProcesses.remove(app);
17738                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17739                        + " to " + app.curProcState + ": "
17740                        + (SystemClock.uptimeMillis()-start) + "ms");
17741            }
17742            app.lastStateTime = now;
17743            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17744                    mTestPssMode, isSleeping(), now);
17745            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17746                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17747                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17748                    + (app.nextPssTime-now) + ": " + app);
17749        } else {
17750            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17751                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17752                    mTestPssMode)))) {
17753                requestPssLocked(app, app.setProcState);
17754                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17755                        mTestPssMode, isSleeping(), now);
17756            } else if (false && DEBUG_PSS) {
17757                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17758            }
17759        }
17760        if (app.setProcState != app.curProcState) {
17761            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17762                    "Proc state change of " + app.processName
17763                    + " to " + app.curProcState);
17764            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17765            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17766            if (setImportant && !curImportant) {
17767                // This app is no longer something we consider important enough to allow to
17768                // use arbitrary amounts of battery power.  Note
17769                // its current wake lock time to later know to kill it if
17770                // it is not behaving well.
17771                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17772                synchronized (stats) {
17773                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17774                            app.pid, SystemClock.elapsedRealtime());
17775                }
17776                app.lastCpuTime = app.curCpuTime;
17777
17778            }
17779            app.setProcState = app.curProcState;
17780            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17781                app.notCachedSinceIdle = false;
17782            }
17783            if (!doingAll) {
17784                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17785            } else {
17786                app.procStateChanged = true;
17787            }
17788        }
17789
17790        if (changes != 0) {
17791            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17792            int i = mPendingProcessChanges.size()-1;
17793            ProcessChangeItem item = null;
17794            while (i >= 0) {
17795                item = mPendingProcessChanges.get(i);
17796                if (item.pid == app.pid) {
17797                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17798                    break;
17799                }
17800                i--;
17801            }
17802            if (i < 0) {
17803                // No existing item in pending changes; need a new one.
17804                final int NA = mAvailProcessChanges.size();
17805                if (NA > 0) {
17806                    item = mAvailProcessChanges.remove(NA-1);
17807                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17808                } else {
17809                    item = new ProcessChangeItem();
17810                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17811                }
17812                item.changes = 0;
17813                item.pid = app.pid;
17814                item.uid = app.info.uid;
17815                if (mPendingProcessChanges.size() == 0) {
17816                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17817                            "*** Enqueueing dispatch processes changed!");
17818                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17819                }
17820                mPendingProcessChanges.add(item);
17821            }
17822            item.changes |= changes;
17823            item.processState = app.repProcState;
17824            item.foregroundActivities = app.repForegroundActivities;
17825            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17826                    + Integer.toHexString(System.identityHashCode(item))
17827                    + " " + app.toShortString() + ": changes=" + item.changes
17828                    + " procState=" + item.processState
17829                    + " foreground=" + item.foregroundActivities
17830                    + " type=" + app.adjType + " source=" + app.adjSource
17831                    + " target=" + app.adjTarget);
17832        }
17833
17834        return success;
17835    }
17836
17837    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17838        if (proc.thread != null) {
17839            if (proc.baseProcessTracker != null) {
17840                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17841            }
17842            if (proc.repProcState >= 0) {
17843                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17844                        proc.repProcState);
17845            }
17846        }
17847    }
17848
17849    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17850            ProcessRecord TOP_APP, boolean doingAll, long now) {
17851        if (app.thread == null) {
17852            return false;
17853        }
17854
17855        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17856
17857        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17858    }
17859
17860    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17861            boolean oomAdj) {
17862        if (isForeground != proc.foregroundServices) {
17863            proc.foregroundServices = isForeground;
17864            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17865                    proc.info.uid);
17866            if (isForeground) {
17867                if (curProcs == null) {
17868                    curProcs = new ArrayList<ProcessRecord>();
17869                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17870                }
17871                if (!curProcs.contains(proc)) {
17872                    curProcs.add(proc);
17873                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17874                            proc.info.packageName, proc.info.uid);
17875                }
17876            } else {
17877                if (curProcs != null) {
17878                    if (curProcs.remove(proc)) {
17879                        mBatteryStatsService.noteEvent(
17880                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17881                                proc.info.packageName, proc.info.uid);
17882                        if (curProcs.size() <= 0) {
17883                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17884                        }
17885                    }
17886                }
17887            }
17888            if (oomAdj) {
17889                updateOomAdjLocked();
17890            }
17891        }
17892    }
17893
17894    private final ActivityRecord resumedAppLocked() {
17895        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17896        String pkg;
17897        int uid;
17898        if (act != null) {
17899            pkg = act.packageName;
17900            uid = act.info.applicationInfo.uid;
17901        } else {
17902            pkg = null;
17903            uid = -1;
17904        }
17905        // Has the UID or resumed package name changed?
17906        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17907                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17908            if (mCurResumedPackage != null) {
17909                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17910                        mCurResumedPackage, mCurResumedUid);
17911            }
17912            mCurResumedPackage = pkg;
17913            mCurResumedUid = uid;
17914            if (mCurResumedPackage != null) {
17915                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17916                        mCurResumedPackage, mCurResumedUid);
17917            }
17918        }
17919        return act;
17920    }
17921
17922    final boolean updateOomAdjLocked(ProcessRecord app) {
17923        final ActivityRecord TOP_ACT = resumedAppLocked();
17924        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17925        final boolean wasCached = app.cached;
17926
17927        mAdjSeq++;
17928
17929        // This is the desired cached adjusment we want to tell it to use.
17930        // If our app is currently cached, we know it, and that is it.  Otherwise,
17931        // we don't know it yet, and it needs to now be cached we will then
17932        // need to do a complete oom adj.
17933        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17934                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17935        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17936                SystemClock.uptimeMillis());
17937        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17938            // Changed to/from cached state, so apps after it in the LRU
17939            // list may also be changed.
17940            updateOomAdjLocked();
17941        }
17942        return success;
17943    }
17944
17945    final void updateOomAdjLocked() {
17946        final ActivityRecord TOP_ACT = resumedAppLocked();
17947        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17948        final long now = SystemClock.uptimeMillis();
17949        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17950        final int N = mLruProcesses.size();
17951
17952        if (false) {
17953            RuntimeException e = new RuntimeException();
17954            e.fillInStackTrace();
17955            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17956        }
17957
17958        mAdjSeq++;
17959        mNewNumServiceProcs = 0;
17960        mNewNumAServiceProcs = 0;
17961
17962        final int emptyProcessLimit;
17963        final int cachedProcessLimit;
17964        if (mProcessLimit <= 0) {
17965            emptyProcessLimit = cachedProcessLimit = 0;
17966        } else if (mProcessLimit == 1) {
17967            emptyProcessLimit = 1;
17968            cachedProcessLimit = 0;
17969        } else {
17970            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17971            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17972        }
17973
17974        // Let's determine how many processes we have running vs.
17975        // how many slots we have for background processes; we may want
17976        // to put multiple processes in a slot of there are enough of
17977        // them.
17978        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17979                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17980        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17981        if (numEmptyProcs > cachedProcessLimit) {
17982            // If there are more empty processes than our limit on cached
17983            // processes, then use the cached process limit for the factor.
17984            // This ensures that the really old empty processes get pushed
17985            // down to the bottom, so if we are running low on memory we will
17986            // have a better chance at keeping around more cached processes
17987            // instead of a gazillion empty processes.
17988            numEmptyProcs = cachedProcessLimit;
17989        }
17990        int emptyFactor = numEmptyProcs/numSlots;
17991        if (emptyFactor < 1) emptyFactor = 1;
17992        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17993        if (cachedFactor < 1) cachedFactor = 1;
17994        int stepCached = 0;
17995        int stepEmpty = 0;
17996        int numCached = 0;
17997        int numEmpty = 0;
17998        int numTrimming = 0;
17999
18000        mNumNonCachedProcs = 0;
18001        mNumCachedHiddenProcs = 0;
18002
18003        // First update the OOM adjustment for each of the
18004        // application processes based on their current state.
18005        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18006        int nextCachedAdj = curCachedAdj+1;
18007        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18008        int nextEmptyAdj = curEmptyAdj+2;
18009        for (int i=N-1; i>=0; i--) {
18010            ProcessRecord app = mLruProcesses.get(i);
18011            if (!app.killedByAm && app.thread != null) {
18012                app.procStateChanged = false;
18013                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18014
18015                // If we haven't yet assigned the final cached adj
18016                // to the process, do that now.
18017                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18018                    switch (app.curProcState) {
18019                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18020                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18021                            // This process is a cached process holding activities...
18022                            // assign it the next cached value for that type, and then
18023                            // step that cached level.
18024                            app.curRawAdj = curCachedAdj;
18025                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18026                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18027                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18028                                    + ")");
18029                            if (curCachedAdj != nextCachedAdj) {
18030                                stepCached++;
18031                                if (stepCached >= cachedFactor) {
18032                                    stepCached = 0;
18033                                    curCachedAdj = nextCachedAdj;
18034                                    nextCachedAdj += 2;
18035                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18036                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18037                                    }
18038                                }
18039                            }
18040                            break;
18041                        default:
18042                            // For everything else, assign next empty cached process
18043                            // level and bump that up.  Note that this means that
18044                            // long-running services that have dropped down to the
18045                            // cached level will be treated as empty (since their process
18046                            // state is still as a service), which is what we want.
18047                            app.curRawAdj = curEmptyAdj;
18048                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18049                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18050                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18051                                    + ")");
18052                            if (curEmptyAdj != nextEmptyAdj) {
18053                                stepEmpty++;
18054                                if (stepEmpty >= emptyFactor) {
18055                                    stepEmpty = 0;
18056                                    curEmptyAdj = nextEmptyAdj;
18057                                    nextEmptyAdj += 2;
18058                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18059                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18060                                    }
18061                                }
18062                            }
18063                            break;
18064                    }
18065                }
18066
18067                applyOomAdjLocked(app, TOP_APP, true, now);
18068
18069                // Count the number of process types.
18070                switch (app.curProcState) {
18071                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18072                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18073                        mNumCachedHiddenProcs++;
18074                        numCached++;
18075                        if (numCached > cachedProcessLimit) {
18076                            app.kill("cached #" + numCached, true);
18077                        }
18078                        break;
18079                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18080                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18081                                && app.lastActivityTime < oldTime) {
18082                            app.kill("empty for "
18083                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18084                                    / 1000) + "s", true);
18085                        } else {
18086                            numEmpty++;
18087                            if (numEmpty > emptyProcessLimit) {
18088                                app.kill("empty #" + numEmpty, true);
18089                            }
18090                        }
18091                        break;
18092                    default:
18093                        mNumNonCachedProcs++;
18094                        break;
18095                }
18096
18097                if (app.isolated && app.services.size() <= 0) {
18098                    // If this is an isolated process, and there are no
18099                    // services running in it, then the process is no longer
18100                    // needed.  We agressively kill these because we can by
18101                    // definition not re-use the same process again, and it is
18102                    // good to avoid having whatever code was running in them
18103                    // left sitting around after no longer needed.
18104                    app.kill("isolated not needed", true);
18105                }
18106
18107                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18108                        && !app.killedByAm) {
18109                    numTrimming++;
18110                }
18111            }
18112        }
18113
18114        mNumServiceProcs = mNewNumServiceProcs;
18115
18116        // Now determine the memory trimming level of background processes.
18117        // Unfortunately we need to start at the back of the list to do this
18118        // properly.  We only do this if the number of background apps we
18119        // are managing to keep around is less than half the maximum we desire;
18120        // if we are keeping a good number around, we'll let them use whatever
18121        // memory they want.
18122        final int numCachedAndEmpty = numCached + numEmpty;
18123        int memFactor;
18124        if (numCached <= ProcessList.TRIM_CACHED_APPS
18125                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18126            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18127                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18128            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18129                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18130            } else {
18131                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18132            }
18133        } else {
18134            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18135        }
18136        // We always allow the memory level to go up (better).  We only allow it to go
18137        // down if we are in a state where that is allowed, *and* the total number of processes
18138        // has gone down since last time.
18139        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18140                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18141                + " last=" + mLastNumProcesses);
18142        if (memFactor > mLastMemoryLevel) {
18143            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18144                memFactor = mLastMemoryLevel;
18145                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18146            }
18147        }
18148        mLastMemoryLevel = memFactor;
18149        mLastNumProcesses = mLruProcesses.size();
18150        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18151        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18152        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18153            if (mLowRamStartTime == 0) {
18154                mLowRamStartTime = now;
18155            }
18156            int step = 0;
18157            int fgTrimLevel;
18158            switch (memFactor) {
18159                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18160                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18161                    break;
18162                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18163                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18164                    break;
18165                default:
18166                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18167                    break;
18168            }
18169            int factor = numTrimming/3;
18170            int minFactor = 2;
18171            if (mHomeProcess != null) minFactor++;
18172            if (mPreviousProcess != null) minFactor++;
18173            if (factor < minFactor) factor = minFactor;
18174            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18175            for (int i=N-1; i>=0; i--) {
18176                ProcessRecord app = mLruProcesses.get(i);
18177                if (allChanged || app.procStateChanged) {
18178                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18179                    app.procStateChanged = false;
18180                }
18181                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18182                        && !app.killedByAm) {
18183                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18184                        try {
18185                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18186                                    "Trimming memory of " + app.processName
18187                                    + " to " + curLevel);
18188                            app.thread.scheduleTrimMemory(curLevel);
18189                        } catch (RemoteException e) {
18190                        }
18191                        if (false) {
18192                            // For now we won't do this; our memory trimming seems
18193                            // to be good enough at this point that destroying
18194                            // activities causes more harm than good.
18195                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18196                                    && app != mHomeProcess && app != mPreviousProcess) {
18197                                // Need to do this on its own message because the stack may not
18198                                // be in a consistent state at this point.
18199                                // For these apps we will also finish their activities
18200                                // to help them free memory.
18201                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18202                            }
18203                        }
18204                    }
18205                    app.trimMemoryLevel = curLevel;
18206                    step++;
18207                    if (step >= factor) {
18208                        step = 0;
18209                        switch (curLevel) {
18210                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18211                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18212                                break;
18213                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18214                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18215                                break;
18216                        }
18217                    }
18218                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18219                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18220                            && app.thread != null) {
18221                        try {
18222                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18223                                    "Trimming memory of heavy-weight " + app.processName
18224                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18225                            app.thread.scheduleTrimMemory(
18226                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18227                        } catch (RemoteException e) {
18228                        }
18229                    }
18230                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18231                } else {
18232                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18233                            || app.systemNoUi) && app.pendingUiClean) {
18234                        // If this application is now in the background and it
18235                        // had done UI, then give it the special trim level to
18236                        // have it free UI resources.
18237                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18238                        if (app.trimMemoryLevel < level && app.thread != null) {
18239                            try {
18240                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18241                                        "Trimming memory of bg-ui " + app.processName
18242                                        + " to " + level);
18243                                app.thread.scheduleTrimMemory(level);
18244                            } catch (RemoteException e) {
18245                            }
18246                        }
18247                        app.pendingUiClean = false;
18248                    }
18249                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18250                        try {
18251                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18252                                    "Trimming memory of fg " + app.processName
18253                                    + " to " + fgTrimLevel);
18254                            app.thread.scheduleTrimMemory(fgTrimLevel);
18255                        } catch (RemoteException e) {
18256                        }
18257                    }
18258                    app.trimMemoryLevel = fgTrimLevel;
18259                }
18260            }
18261        } else {
18262            if (mLowRamStartTime != 0) {
18263                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18264                mLowRamStartTime = 0;
18265            }
18266            for (int i=N-1; i>=0; i--) {
18267                ProcessRecord app = mLruProcesses.get(i);
18268                if (allChanged || app.procStateChanged) {
18269                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18270                    app.procStateChanged = false;
18271                }
18272                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18273                        || app.systemNoUi) && app.pendingUiClean) {
18274                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18275                            && app.thread != null) {
18276                        try {
18277                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18278                                    "Trimming memory of ui hidden " + app.processName
18279                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18280                            app.thread.scheduleTrimMemory(
18281                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18282                        } catch (RemoteException e) {
18283                        }
18284                    }
18285                    app.pendingUiClean = false;
18286                }
18287                app.trimMemoryLevel = 0;
18288            }
18289        }
18290
18291        if (mAlwaysFinishActivities) {
18292            // Need to do this on its own message because the stack may not
18293            // be in a consistent state at this point.
18294            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18295        }
18296
18297        if (allChanged) {
18298            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18299        }
18300
18301        if (mProcessStats.shouldWriteNowLocked(now)) {
18302            mHandler.post(new Runnable() {
18303                @Override public void run() {
18304                    synchronized (ActivityManagerService.this) {
18305                        mProcessStats.writeStateAsyncLocked();
18306                    }
18307                }
18308            });
18309        }
18310
18311        if (DEBUG_OOM_ADJ) {
18312            if (false) {
18313                RuntimeException here = new RuntimeException("here");
18314                here.fillInStackTrace();
18315                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18316            } else {
18317                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18318            }
18319        }
18320    }
18321
18322    final void trimApplications() {
18323        synchronized (this) {
18324            int i;
18325
18326            // First remove any unused application processes whose package
18327            // has been removed.
18328            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18329                final ProcessRecord app = mRemovedProcesses.get(i);
18330                if (app.activities.size() == 0
18331                        && app.curReceiver == null && app.services.size() == 0) {
18332                    Slog.i(
18333                        TAG, "Exiting empty application process "
18334                        + app.processName + " ("
18335                        + (app.thread != null ? app.thread.asBinder() : null)
18336                        + ")\n");
18337                    if (app.pid > 0 && app.pid != MY_PID) {
18338                        app.kill("empty", false);
18339                    } else {
18340                        try {
18341                            app.thread.scheduleExit();
18342                        } catch (Exception e) {
18343                            // Ignore exceptions.
18344                        }
18345                    }
18346                    cleanUpApplicationRecordLocked(app, false, true, -1);
18347                    mRemovedProcesses.remove(i);
18348
18349                    if (app.persistent) {
18350                        addAppLocked(app.info, false, null /* ABI override */);
18351                    }
18352                }
18353            }
18354
18355            // Now update the oom adj for all processes.
18356            updateOomAdjLocked();
18357        }
18358    }
18359
18360    /** This method sends the specified signal to each of the persistent apps */
18361    public void signalPersistentProcesses(int sig) throws RemoteException {
18362        if (sig != Process.SIGNAL_USR1) {
18363            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18364        }
18365
18366        synchronized (this) {
18367            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18368                    != PackageManager.PERMISSION_GRANTED) {
18369                throw new SecurityException("Requires permission "
18370                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18371            }
18372
18373            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18374                ProcessRecord r = mLruProcesses.get(i);
18375                if (r.thread != null && r.persistent) {
18376                    Process.sendSignal(r.pid, sig);
18377                }
18378            }
18379        }
18380    }
18381
18382    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18383        if (proc == null || proc == mProfileProc) {
18384            proc = mProfileProc;
18385            profileType = mProfileType;
18386            clearProfilerLocked();
18387        }
18388        if (proc == null) {
18389            return;
18390        }
18391        try {
18392            proc.thread.profilerControl(false, null, profileType);
18393        } catch (RemoteException e) {
18394            throw new IllegalStateException("Process disappeared");
18395        }
18396    }
18397
18398    private void clearProfilerLocked() {
18399        if (mProfileFd != null) {
18400            try {
18401                mProfileFd.close();
18402            } catch (IOException e) {
18403            }
18404        }
18405        mProfileApp = null;
18406        mProfileProc = null;
18407        mProfileFile = null;
18408        mProfileType = 0;
18409        mAutoStopProfiler = false;
18410        mSamplingInterval = 0;
18411    }
18412
18413    public boolean profileControl(String process, int userId, boolean start,
18414            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18415
18416        try {
18417            synchronized (this) {
18418                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18419                // its own permission.
18420                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18421                        != PackageManager.PERMISSION_GRANTED) {
18422                    throw new SecurityException("Requires permission "
18423                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18424                }
18425
18426                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18427                    throw new IllegalArgumentException("null profile info or fd");
18428                }
18429
18430                ProcessRecord proc = null;
18431                if (process != null) {
18432                    proc = findProcessLocked(process, userId, "profileControl");
18433                }
18434
18435                if (start && (proc == null || proc.thread == null)) {
18436                    throw new IllegalArgumentException("Unknown process: " + process);
18437                }
18438
18439                if (start) {
18440                    stopProfilerLocked(null, 0);
18441                    setProfileApp(proc.info, proc.processName, profilerInfo);
18442                    mProfileProc = proc;
18443                    mProfileType = profileType;
18444                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18445                    try {
18446                        fd = fd.dup();
18447                    } catch (IOException e) {
18448                        fd = null;
18449                    }
18450                    profilerInfo.profileFd = fd;
18451                    proc.thread.profilerControl(start, profilerInfo, profileType);
18452                    fd = null;
18453                    mProfileFd = null;
18454                } else {
18455                    stopProfilerLocked(proc, profileType);
18456                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18457                        try {
18458                            profilerInfo.profileFd.close();
18459                        } catch (IOException e) {
18460                        }
18461                    }
18462                }
18463
18464                return true;
18465            }
18466        } catch (RemoteException e) {
18467            throw new IllegalStateException("Process disappeared");
18468        } finally {
18469            if (profilerInfo != null && profilerInfo.profileFd != null) {
18470                try {
18471                    profilerInfo.profileFd.close();
18472                } catch (IOException e) {
18473                }
18474            }
18475        }
18476    }
18477
18478    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18479        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18480                userId, true, ALLOW_FULL_ONLY, callName, null);
18481        ProcessRecord proc = null;
18482        try {
18483            int pid = Integer.parseInt(process);
18484            synchronized (mPidsSelfLocked) {
18485                proc = mPidsSelfLocked.get(pid);
18486            }
18487        } catch (NumberFormatException e) {
18488        }
18489
18490        if (proc == null) {
18491            ArrayMap<String, SparseArray<ProcessRecord>> all
18492                    = mProcessNames.getMap();
18493            SparseArray<ProcessRecord> procs = all.get(process);
18494            if (procs != null && procs.size() > 0) {
18495                proc = procs.valueAt(0);
18496                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18497                    for (int i=1; i<procs.size(); i++) {
18498                        ProcessRecord thisProc = procs.valueAt(i);
18499                        if (thisProc.userId == userId) {
18500                            proc = thisProc;
18501                            break;
18502                        }
18503                    }
18504                }
18505            }
18506        }
18507
18508        return proc;
18509    }
18510
18511    public boolean dumpHeap(String process, int userId, boolean managed,
18512            String path, ParcelFileDescriptor fd) throws RemoteException {
18513
18514        try {
18515            synchronized (this) {
18516                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18517                // its own permission (same as profileControl).
18518                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18519                        != PackageManager.PERMISSION_GRANTED) {
18520                    throw new SecurityException("Requires permission "
18521                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18522                }
18523
18524                if (fd == null) {
18525                    throw new IllegalArgumentException("null fd");
18526                }
18527
18528                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18529                if (proc == null || proc.thread == null) {
18530                    throw new IllegalArgumentException("Unknown process: " + process);
18531                }
18532
18533                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18534                if (!isDebuggable) {
18535                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18536                        throw new SecurityException("Process not debuggable: " + proc);
18537                    }
18538                }
18539
18540                proc.thread.dumpHeap(managed, path, fd);
18541                fd = null;
18542                return true;
18543            }
18544        } catch (RemoteException e) {
18545            throw new IllegalStateException("Process disappeared");
18546        } finally {
18547            if (fd != null) {
18548                try {
18549                    fd.close();
18550                } catch (IOException e) {
18551                }
18552            }
18553        }
18554    }
18555
18556    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18557    public void monitor() {
18558        synchronized (this) { }
18559    }
18560
18561    void onCoreSettingsChange(Bundle settings) {
18562        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18563            ProcessRecord processRecord = mLruProcesses.get(i);
18564            try {
18565                if (processRecord.thread != null) {
18566                    processRecord.thread.setCoreSettings(settings);
18567                }
18568            } catch (RemoteException re) {
18569                /* ignore */
18570            }
18571        }
18572    }
18573
18574    // Multi-user methods
18575
18576    /**
18577     * Start user, if its not already running, but don't bring it to foreground.
18578     */
18579    @Override
18580    public boolean startUserInBackground(final int userId) {
18581        return startUser(userId, /* foreground */ false);
18582    }
18583
18584    /**
18585     * Start user, if its not already running, and bring it to foreground.
18586     */
18587    boolean startUserInForeground(final int userId, Dialog dlg) {
18588        boolean result = startUser(userId, /* foreground */ true);
18589        dlg.dismiss();
18590        return result;
18591    }
18592
18593    /**
18594     * Refreshes the list of users related to the current user when either a
18595     * user switch happens or when a new related user is started in the
18596     * background.
18597     */
18598    private void updateCurrentProfileIdsLocked() {
18599        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18600                mCurrentUserId, false /* enabledOnly */);
18601        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18602        for (int i = 0; i < currentProfileIds.length; i++) {
18603            currentProfileIds[i] = profiles.get(i).id;
18604        }
18605        mCurrentProfileIds = currentProfileIds;
18606
18607        synchronized (mUserProfileGroupIdsSelfLocked) {
18608            mUserProfileGroupIdsSelfLocked.clear();
18609            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18610            for (int i = 0; i < users.size(); i++) {
18611                UserInfo user = users.get(i);
18612                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18613                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18614                }
18615            }
18616        }
18617    }
18618
18619    private Set getProfileIdsLocked(int userId) {
18620        Set userIds = new HashSet<Integer>();
18621        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18622                userId, false /* enabledOnly */);
18623        for (UserInfo user : profiles) {
18624            userIds.add(Integer.valueOf(user.id));
18625        }
18626        return userIds;
18627    }
18628
18629    @Override
18630    public boolean switchUser(final int userId) {
18631        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18632        String userName;
18633        synchronized (this) {
18634            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18635            if (userInfo == null) {
18636                Slog.w(TAG, "No user info for user #" + userId);
18637                return false;
18638            }
18639            if (userInfo.isManagedProfile()) {
18640                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18641                return false;
18642            }
18643            userName = userInfo.name;
18644            mTargetUserId = userId;
18645        }
18646        mHandler.removeMessages(START_USER_SWITCH_MSG);
18647        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18648        return true;
18649    }
18650
18651    private void showUserSwitchDialog(int userId, String userName) {
18652        // The dialog will show and then initiate the user switch by calling startUserInForeground
18653        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18654                true /* above system */);
18655        d.show();
18656    }
18657
18658    private boolean startUser(final int userId, final boolean foreground) {
18659        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18660                != PackageManager.PERMISSION_GRANTED) {
18661            String msg = "Permission Denial: switchUser() from pid="
18662                    + Binder.getCallingPid()
18663                    + ", uid=" + Binder.getCallingUid()
18664                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18665            Slog.w(TAG, msg);
18666            throw new SecurityException(msg);
18667        }
18668
18669        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18670
18671        final long ident = Binder.clearCallingIdentity();
18672        try {
18673            synchronized (this) {
18674                final int oldUserId = mCurrentUserId;
18675                if (oldUserId == userId) {
18676                    return true;
18677                }
18678
18679                mStackSupervisor.setLockTaskModeLocked(null, false);
18680
18681                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18682                if (userInfo == null) {
18683                    Slog.w(TAG, "No user info for user #" + userId);
18684                    return false;
18685                }
18686                if (foreground && userInfo.isManagedProfile()) {
18687                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18688                    return false;
18689                }
18690
18691                if (foreground) {
18692                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18693                            R.anim.screen_user_enter);
18694                }
18695
18696                boolean needStart = false;
18697
18698                // If the user we are switching to is not currently started, then
18699                // we need to start it now.
18700                if (mStartedUsers.get(userId) == null) {
18701                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18702                    updateStartedUserArrayLocked();
18703                    needStart = true;
18704                }
18705
18706                final Integer userIdInt = Integer.valueOf(userId);
18707                mUserLru.remove(userIdInt);
18708                mUserLru.add(userIdInt);
18709
18710                if (foreground) {
18711                    mCurrentUserId = userId;
18712                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18713                    updateCurrentProfileIdsLocked();
18714                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18715                    // Once the internal notion of the active user has switched, we lock the device
18716                    // with the option to show the user switcher on the keyguard.
18717                    mWindowManager.lockNow(null);
18718                } else {
18719                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18720                    updateCurrentProfileIdsLocked();
18721                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18722                    mUserLru.remove(currentUserIdInt);
18723                    mUserLru.add(currentUserIdInt);
18724                }
18725
18726                final UserStartedState uss = mStartedUsers.get(userId);
18727
18728                // Make sure user is in the started state.  If it is currently
18729                // stopping, we need to knock that off.
18730                if (uss.mState == UserStartedState.STATE_STOPPING) {
18731                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18732                    // so we can just fairly silently bring the user back from
18733                    // the almost-dead.
18734                    uss.mState = UserStartedState.STATE_RUNNING;
18735                    updateStartedUserArrayLocked();
18736                    needStart = true;
18737                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18738                    // This means ACTION_SHUTDOWN has been sent, so we will
18739                    // need to treat this as a new boot of the user.
18740                    uss.mState = UserStartedState.STATE_BOOTING;
18741                    updateStartedUserArrayLocked();
18742                    needStart = true;
18743                }
18744
18745                if (uss.mState == UserStartedState.STATE_BOOTING) {
18746                    // Booting up a new user, need to tell system services about it.
18747                    // Note that this is on the same handler as scheduling of broadcasts,
18748                    // which is important because it needs to go first.
18749                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18750                }
18751
18752                if (foreground) {
18753                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18754                            oldUserId));
18755                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18756                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18757                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18758                            oldUserId, userId, uss));
18759                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18760                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18761                }
18762
18763                if (needStart) {
18764                    // Send USER_STARTED broadcast
18765                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18766                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18767                            | Intent.FLAG_RECEIVER_FOREGROUND);
18768                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18769                    broadcastIntentLocked(null, null, intent,
18770                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18771                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18772                }
18773
18774                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18775                    if (userId != UserHandle.USER_OWNER) {
18776                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18777                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18778                        broadcastIntentLocked(null, null, intent, null,
18779                                new IIntentReceiver.Stub() {
18780                                    public void performReceive(Intent intent, int resultCode,
18781                                            String data, Bundle extras, boolean ordered,
18782                                            boolean sticky, int sendingUser) {
18783                                        onUserInitialized(uss, foreground, oldUserId, userId);
18784                                    }
18785                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18786                                true, false, MY_PID, Process.SYSTEM_UID,
18787                                userId);
18788                        uss.initializing = true;
18789                    } else {
18790                        getUserManagerLocked().makeInitialized(userInfo.id);
18791                    }
18792                }
18793
18794                if (foreground) {
18795                    if (!uss.initializing) {
18796                        moveUserToForeground(uss, oldUserId, userId);
18797                    }
18798                } else {
18799                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18800                }
18801
18802                if (needStart) {
18803                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18804                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18805                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18806                    broadcastIntentLocked(null, null, intent,
18807                            null, new IIntentReceiver.Stub() {
18808                                @Override
18809                                public void performReceive(Intent intent, int resultCode, String data,
18810                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18811                                        throws RemoteException {
18812                                }
18813                            }, 0, null, null,
18814                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18815                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18816                }
18817            }
18818        } finally {
18819            Binder.restoreCallingIdentity(ident);
18820        }
18821
18822        return true;
18823    }
18824
18825    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18826        long ident = Binder.clearCallingIdentity();
18827        try {
18828            Intent intent;
18829            if (oldUserId >= 0) {
18830                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18831                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18832                int count = profiles.size();
18833                for (int i = 0; i < count; i++) {
18834                    int profileUserId = profiles.get(i).id;
18835                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18836                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18837                            | Intent.FLAG_RECEIVER_FOREGROUND);
18838                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18839                    broadcastIntentLocked(null, null, intent,
18840                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18841                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18842                }
18843            }
18844            if (newUserId >= 0) {
18845                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18846                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18847                int count = profiles.size();
18848                for (int i = 0; i < count; i++) {
18849                    int profileUserId = profiles.get(i).id;
18850                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18851                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18852                            | Intent.FLAG_RECEIVER_FOREGROUND);
18853                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18854                    broadcastIntentLocked(null, null, intent,
18855                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18856                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18857                }
18858                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18859                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18860                        | Intent.FLAG_RECEIVER_FOREGROUND);
18861                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18862                broadcastIntentLocked(null, null, intent,
18863                        null, null, 0, null, null,
18864                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18865                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18866            }
18867        } finally {
18868            Binder.restoreCallingIdentity(ident);
18869        }
18870    }
18871
18872    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18873            final int newUserId) {
18874        final int N = mUserSwitchObservers.beginBroadcast();
18875        if (N > 0) {
18876            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18877                int mCount = 0;
18878                @Override
18879                public void sendResult(Bundle data) throws RemoteException {
18880                    synchronized (ActivityManagerService.this) {
18881                        if (mCurUserSwitchCallback == this) {
18882                            mCount++;
18883                            if (mCount == N) {
18884                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18885                            }
18886                        }
18887                    }
18888                }
18889            };
18890            synchronized (this) {
18891                uss.switching = true;
18892                mCurUserSwitchCallback = callback;
18893            }
18894            for (int i=0; i<N; i++) {
18895                try {
18896                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18897                            newUserId, callback);
18898                } catch (RemoteException e) {
18899                }
18900            }
18901        } else {
18902            synchronized (this) {
18903                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18904            }
18905        }
18906        mUserSwitchObservers.finishBroadcast();
18907    }
18908
18909    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18910        synchronized (this) {
18911            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18912            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18913        }
18914    }
18915
18916    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18917        mCurUserSwitchCallback = null;
18918        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18919        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18920                oldUserId, newUserId, uss));
18921    }
18922
18923    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18924        synchronized (this) {
18925            if (foreground) {
18926                moveUserToForeground(uss, oldUserId, newUserId);
18927            }
18928        }
18929
18930        completeSwitchAndInitalize(uss, newUserId, true, false);
18931    }
18932
18933    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18934        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18935        if (homeInFront) {
18936            startHomeActivityLocked(newUserId);
18937        } else {
18938            mStackSupervisor.resumeTopActivitiesLocked();
18939        }
18940        EventLogTags.writeAmSwitchUser(newUserId);
18941        getUserManagerLocked().userForeground(newUserId);
18942        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18943    }
18944
18945    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18946        completeSwitchAndInitalize(uss, newUserId, false, true);
18947    }
18948
18949    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18950            boolean clearInitializing, boolean clearSwitching) {
18951        boolean unfrozen = false;
18952        synchronized (this) {
18953            if (clearInitializing) {
18954                uss.initializing = false;
18955                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18956            }
18957            if (clearSwitching) {
18958                uss.switching = false;
18959            }
18960            if (!uss.switching && !uss.initializing) {
18961                mWindowManager.stopFreezingScreen();
18962                unfrozen = true;
18963            }
18964        }
18965        if (unfrozen) {
18966            final int N = mUserSwitchObservers.beginBroadcast();
18967            for (int i=0; i<N; i++) {
18968                try {
18969                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18970                } catch (RemoteException e) {
18971                }
18972            }
18973            mUserSwitchObservers.finishBroadcast();
18974        }
18975    }
18976
18977    void scheduleStartProfilesLocked() {
18978        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18979            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18980                    DateUtils.SECOND_IN_MILLIS);
18981        }
18982    }
18983
18984    void startProfilesLocked() {
18985        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18986        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18987                mCurrentUserId, false /* enabledOnly */);
18988        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18989        for (UserInfo user : profiles) {
18990            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18991                    && user.id != mCurrentUserId) {
18992                toStart.add(user);
18993            }
18994        }
18995        final int n = toStart.size();
18996        int i = 0;
18997        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18998            startUserInBackground(toStart.get(i).id);
18999        }
19000        if (i < n) {
19001            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19002        }
19003    }
19004
19005    void finishUserBoot(UserStartedState uss) {
19006        synchronized (this) {
19007            if (uss.mState == UserStartedState.STATE_BOOTING
19008                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19009                uss.mState = UserStartedState.STATE_RUNNING;
19010                final int userId = uss.mHandle.getIdentifier();
19011                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19012                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19013                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19014                broadcastIntentLocked(null, null, intent,
19015                        null, null, 0, null, null,
19016                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19017                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19018            }
19019        }
19020    }
19021
19022    void finishUserSwitch(UserStartedState uss) {
19023        synchronized (this) {
19024            finishUserBoot(uss);
19025
19026            startProfilesLocked();
19027
19028            int num = mUserLru.size();
19029            int i = 0;
19030            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19031                Integer oldUserId = mUserLru.get(i);
19032                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19033                if (oldUss == null) {
19034                    // Shouldn't happen, but be sane if it does.
19035                    mUserLru.remove(i);
19036                    num--;
19037                    continue;
19038                }
19039                if (oldUss.mState == UserStartedState.STATE_STOPPING
19040                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19041                    // This user is already stopping, doesn't count.
19042                    num--;
19043                    i++;
19044                    continue;
19045                }
19046                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19047                    // Owner and current can't be stopped, but count as running.
19048                    i++;
19049                    continue;
19050                }
19051                // This is a user to be stopped.
19052                stopUserLocked(oldUserId, null);
19053                num--;
19054                i++;
19055            }
19056        }
19057    }
19058
19059    @Override
19060    public int stopUser(final int userId, final IStopUserCallback callback) {
19061        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19062                != PackageManager.PERMISSION_GRANTED) {
19063            String msg = "Permission Denial: switchUser() from pid="
19064                    + Binder.getCallingPid()
19065                    + ", uid=" + Binder.getCallingUid()
19066                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19067            Slog.w(TAG, msg);
19068            throw new SecurityException(msg);
19069        }
19070        if (userId <= 0) {
19071            throw new IllegalArgumentException("Can't stop primary user " + userId);
19072        }
19073        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19074        synchronized (this) {
19075            return stopUserLocked(userId, callback);
19076        }
19077    }
19078
19079    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19080        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19081        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19082            return ActivityManager.USER_OP_IS_CURRENT;
19083        }
19084
19085        final UserStartedState uss = mStartedUsers.get(userId);
19086        if (uss == null) {
19087            // User is not started, nothing to do...  but we do need to
19088            // callback if requested.
19089            if (callback != null) {
19090                mHandler.post(new Runnable() {
19091                    @Override
19092                    public void run() {
19093                        try {
19094                            callback.userStopped(userId);
19095                        } catch (RemoteException e) {
19096                        }
19097                    }
19098                });
19099            }
19100            return ActivityManager.USER_OP_SUCCESS;
19101        }
19102
19103        if (callback != null) {
19104            uss.mStopCallbacks.add(callback);
19105        }
19106
19107        if (uss.mState != UserStartedState.STATE_STOPPING
19108                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19109            uss.mState = UserStartedState.STATE_STOPPING;
19110            updateStartedUserArrayLocked();
19111
19112            long ident = Binder.clearCallingIdentity();
19113            try {
19114                // We are going to broadcast ACTION_USER_STOPPING and then
19115                // once that is done send a final ACTION_SHUTDOWN and then
19116                // stop the user.
19117                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19118                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19119                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19120                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19121                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19122                // This is the result receiver for the final shutdown broadcast.
19123                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19124                    @Override
19125                    public void performReceive(Intent intent, int resultCode, String data,
19126                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19127                        finishUserStop(uss);
19128                    }
19129                };
19130                // This is the result receiver for the initial stopping broadcast.
19131                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19132                    @Override
19133                    public void performReceive(Intent intent, int resultCode, String data,
19134                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19135                        // On to the next.
19136                        synchronized (ActivityManagerService.this) {
19137                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19138                                // Whoops, we are being started back up.  Abort, abort!
19139                                return;
19140                            }
19141                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19142                        }
19143                        mBatteryStatsService.noteEvent(
19144                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19145                                Integer.toString(userId), userId);
19146                        mSystemServiceManager.stopUser(userId);
19147                        broadcastIntentLocked(null, null, shutdownIntent,
19148                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19149                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19150                    }
19151                };
19152                // Kick things off.
19153                broadcastIntentLocked(null, null, stoppingIntent,
19154                        null, stoppingReceiver, 0, null, null,
19155                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19156                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19157            } finally {
19158                Binder.restoreCallingIdentity(ident);
19159            }
19160        }
19161
19162        return ActivityManager.USER_OP_SUCCESS;
19163    }
19164
19165    void finishUserStop(UserStartedState uss) {
19166        final int userId = uss.mHandle.getIdentifier();
19167        boolean stopped;
19168        ArrayList<IStopUserCallback> callbacks;
19169        synchronized (this) {
19170            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19171            if (mStartedUsers.get(userId) != uss) {
19172                stopped = false;
19173            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19174                stopped = false;
19175            } else {
19176                stopped = true;
19177                // User can no longer run.
19178                mStartedUsers.remove(userId);
19179                mUserLru.remove(Integer.valueOf(userId));
19180                updateStartedUserArrayLocked();
19181
19182                // Clean up all state and processes associated with the user.
19183                // Kill all the processes for the user.
19184                forceStopUserLocked(userId, "finish user");
19185            }
19186
19187            // Explicitly remove the old information in mRecentTasks.
19188            removeRecentTasksForUserLocked(userId);
19189        }
19190
19191        for (int i=0; i<callbacks.size(); i++) {
19192            try {
19193                if (stopped) callbacks.get(i).userStopped(userId);
19194                else callbacks.get(i).userStopAborted(userId);
19195            } catch (RemoteException e) {
19196            }
19197        }
19198
19199        if (stopped) {
19200            mSystemServiceManager.cleanupUser(userId);
19201            synchronized (this) {
19202                mStackSupervisor.removeUserLocked(userId);
19203            }
19204        }
19205    }
19206
19207    @Override
19208    public UserInfo getCurrentUser() {
19209        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19210                != PackageManager.PERMISSION_GRANTED) && (
19211                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19212                != PackageManager.PERMISSION_GRANTED)) {
19213            String msg = "Permission Denial: getCurrentUser() from pid="
19214                    + Binder.getCallingPid()
19215                    + ", uid=" + Binder.getCallingUid()
19216                    + " requires " + INTERACT_ACROSS_USERS;
19217            Slog.w(TAG, msg);
19218            throw new SecurityException(msg);
19219        }
19220        synchronized (this) {
19221            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19222            return getUserManagerLocked().getUserInfo(userId);
19223        }
19224    }
19225
19226    int getCurrentUserIdLocked() {
19227        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19228    }
19229
19230    @Override
19231    public boolean isUserRunning(int userId, boolean orStopped) {
19232        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19233                != PackageManager.PERMISSION_GRANTED) {
19234            String msg = "Permission Denial: isUserRunning() from pid="
19235                    + Binder.getCallingPid()
19236                    + ", uid=" + Binder.getCallingUid()
19237                    + " requires " + INTERACT_ACROSS_USERS;
19238            Slog.w(TAG, msg);
19239            throw new SecurityException(msg);
19240        }
19241        synchronized (this) {
19242            return isUserRunningLocked(userId, orStopped);
19243        }
19244    }
19245
19246    boolean isUserRunningLocked(int userId, boolean orStopped) {
19247        UserStartedState state = mStartedUsers.get(userId);
19248        if (state == null) {
19249            return false;
19250        }
19251        if (orStopped) {
19252            return true;
19253        }
19254        return state.mState != UserStartedState.STATE_STOPPING
19255                && state.mState != UserStartedState.STATE_SHUTDOWN;
19256    }
19257
19258    @Override
19259    public int[] getRunningUserIds() {
19260        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19261                != PackageManager.PERMISSION_GRANTED) {
19262            String msg = "Permission Denial: isUserRunning() from pid="
19263                    + Binder.getCallingPid()
19264                    + ", uid=" + Binder.getCallingUid()
19265                    + " requires " + INTERACT_ACROSS_USERS;
19266            Slog.w(TAG, msg);
19267            throw new SecurityException(msg);
19268        }
19269        synchronized (this) {
19270            return mStartedUserArray;
19271        }
19272    }
19273
19274    private void updateStartedUserArrayLocked() {
19275        int num = 0;
19276        for (int i=0; i<mStartedUsers.size();  i++) {
19277            UserStartedState uss = mStartedUsers.valueAt(i);
19278            // This list does not include stopping users.
19279            if (uss.mState != UserStartedState.STATE_STOPPING
19280                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19281                num++;
19282            }
19283        }
19284        mStartedUserArray = new int[num];
19285        num = 0;
19286        for (int i=0; i<mStartedUsers.size();  i++) {
19287            UserStartedState uss = mStartedUsers.valueAt(i);
19288            if (uss.mState != UserStartedState.STATE_STOPPING
19289                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19290                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19291                num++;
19292            }
19293        }
19294    }
19295
19296    @Override
19297    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19298        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19299                != PackageManager.PERMISSION_GRANTED) {
19300            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19301                    + Binder.getCallingPid()
19302                    + ", uid=" + Binder.getCallingUid()
19303                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19304            Slog.w(TAG, msg);
19305            throw new SecurityException(msg);
19306        }
19307
19308        mUserSwitchObservers.register(observer);
19309    }
19310
19311    @Override
19312    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19313        mUserSwitchObservers.unregister(observer);
19314    }
19315
19316    private boolean userExists(int userId) {
19317        if (userId == 0) {
19318            return true;
19319        }
19320        UserManagerService ums = getUserManagerLocked();
19321        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19322    }
19323
19324    int[] getUsersLocked() {
19325        UserManagerService ums = getUserManagerLocked();
19326        return ums != null ? ums.getUserIds() : new int[] { 0 };
19327    }
19328
19329    UserManagerService getUserManagerLocked() {
19330        if (mUserManager == null) {
19331            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19332            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19333        }
19334        return mUserManager;
19335    }
19336
19337    private int applyUserId(int uid, int userId) {
19338        return UserHandle.getUid(userId, uid);
19339    }
19340
19341    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19342        if (info == null) return null;
19343        ApplicationInfo newInfo = new ApplicationInfo(info);
19344        newInfo.uid = applyUserId(info.uid, userId);
19345        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19346                + info.packageName;
19347        return newInfo;
19348    }
19349
19350    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19351        if (aInfo == null
19352                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19353            return aInfo;
19354        }
19355
19356        ActivityInfo info = new ActivityInfo(aInfo);
19357        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19358        return info;
19359    }
19360
19361    private final class LocalService extends ActivityManagerInternal {
19362        @Override
19363        public void onWakefulnessChanged(int wakefulness) {
19364            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19365        }
19366
19367        @Override
19368        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19369                String processName, String abiOverride, int uid, Runnable crashHandler) {
19370            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19371                    processName, abiOverride, uid, crashHandler);
19372        }
19373    }
19374
19375    /**
19376     * An implementation of IAppTask, that allows an app to manage its own tasks via
19377     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19378     * only the process that calls getAppTasks() can call the AppTask methods.
19379     */
19380    class AppTaskImpl extends IAppTask.Stub {
19381        private int mTaskId;
19382        private int mCallingUid;
19383
19384        public AppTaskImpl(int taskId, int callingUid) {
19385            mTaskId = taskId;
19386            mCallingUid = callingUid;
19387        }
19388
19389        private void checkCaller() {
19390            if (mCallingUid != Binder.getCallingUid()) {
19391                throw new SecurityException("Caller " + mCallingUid
19392                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19393            }
19394        }
19395
19396        @Override
19397        public void finishAndRemoveTask() {
19398            checkCaller();
19399
19400            synchronized (ActivityManagerService.this) {
19401                long origId = Binder.clearCallingIdentity();
19402                try {
19403                    if (!removeTaskByIdLocked(mTaskId, false)) {
19404                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19405                    }
19406                } finally {
19407                    Binder.restoreCallingIdentity(origId);
19408                }
19409            }
19410        }
19411
19412        @Override
19413        public ActivityManager.RecentTaskInfo getTaskInfo() {
19414            checkCaller();
19415
19416            synchronized (ActivityManagerService.this) {
19417                long origId = Binder.clearCallingIdentity();
19418                try {
19419                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19420                    if (tr == null) {
19421                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19422                    }
19423                    return createRecentTaskInfoFromTaskRecord(tr);
19424                } finally {
19425                    Binder.restoreCallingIdentity(origId);
19426                }
19427            }
19428        }
19429
19430        @Override
19431        public void moveToFront() {
19432            checkCaller();
19433
19434            final TaskRecord tr;
19435            synchronized (ActivityManagerService.this) {
19436                tr = recentTaskForIdLocked(mTaskId);
19437                if (tr == null) {
19438                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19439                }
19440                if (tr.getRootActivity() != null) {
19441                    moveTaskToFrontLocked(tr.taskId, 0, null);
19442                    return;
19443                }
19444            }
19445
19446            startActivityFromRecentsInner(tr.taskId, null);
19447        }
19448
19449        @Override
19450        public int startActivity(IBinder whoThread, String callingPackage,
19451                Intent intent, String resolvedType, Bundle options) {
19452            checkCaller();
19453
19454            int callingUser = UserHandle.getCallingUserId();
19455            TaskRecord tr;
19456            IApplicationThread appThread;
19457            synchronized (ActivityManagerService.this) {
19458                tr = recentTaskForIdLocked(mTaskId);
19459                if (tr == null) {
19460                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19461                }
19462                appThread = ApplicationThreadNative.asInterface(whoThread);
19463                if (appThread == null) {
19464                    throw new IllegalArgumentException("Bad app thread " + appThread);
19465                }
19466            }
19467            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19468                    resolvedType, null, null, null, null, 0, 0, null, null,
19469                    null, options, callingUser, null, tr);
19470        }
19471
19472        @Override
19473        public void setExcludeFromRecents(boolean exclude) {
19474            checkCaller();
19475
19476            synchronized (ActivityManagerService.this) {
19477                long origId = Binder.clearCallingIdentity();
19478                try {
19479                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19480                    if (tr == null) {
19481                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19482                    }
19483                    Intent intent = tr.getBaseIntent();
19484                    if (exclude) {
19485                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19486                    } else {
19487                        intent.setFlags(intent.getFlags()
19488                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19489                    }
19490                } finally {
19491                    Binder.restoreCallingIdentity(origId);
19492                }
19493            }
19494        }
19495    }
19496}
19497