ActivityManagerService.java revision ab2df067fc9757f19061b968c53953ca90a4c384
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    final static class Association {
753        final int mSourceUid;
754        final String mSourceProcess;
755        final int mTargetUid;
756        final ComponentName mTargetComponent;
757        final String mTargetProcess;
758
759        int mCount;
760        long mTime;
761
762        int mNesting;
763        long mStartTime;
764
765        Association(int sourceUid, String sourceProcess, int targetUid,
766                ComponentName targetComponent, String targetProcess) {
767            mSourceUid = sourceUid;
768            mSourceProcess = sourceProcess;
769            mTargetUid = targetUid;
770            mTargetComponent = targetComponent;
771            mTargetProcess = targetProcess;
772        }
773    }
774
775    /**
776     * When service association tracking is enabled, this is all of the associations we
777     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
778     * -> association data.
779     */
780    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
781            mAssociations = new SparseArray<>();
782    boolean mTrackingAssociations;
783
784    /**
785     * Backup/restore process management
786     */
787    String mBackupAppName = null;
788    BackupRecord mBackupTarget = null;
789
790    final ProviderMap mProviderMap;
791
792    /**
793     * List of content providers who have clients waiting for them.  The
794     * application is currently being launched and the provider will be
795     * removed from this list once it is published.
796     */
797    final ArrayList<ContentProviderRecord> mLaunchingProviders
798            = new ArrayList<ContentProviderRecord>();
799
800    /**
801     * File storing persisted {@link #mGrantedUriPermissions}.
802     */
803    private final AtomicFile mGrantFile;
804
805    /** XML constants used in {@link #mGrantFile} */
806    private static final String TAG_URI_GRANTS = "uri-grants";
807    private static final String TAG_URI_GRANT = "uri-grant";
808    private static final String ATTR_USER_HANDLE = "userHandle";
809    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
810    private static final String ATTR_TARGET_USER_ID = "targetUserId";
811    private static final String ATTR_SOURCE_PKG = "sourcePkg";
812    private static final String ATTR_TARGET_PKG = "targetPkg";
813    private static final String ATTR_URI = "uri";
814    private static final String ATTR_MODE_FLAGS = "modeFlags";
815    private static final String ATTR_CREATED_TIME = "createdTime";
816    private static final String ATTR_PREFIX = "prefix";
817
818    /**
819     * Global set of specific {@link Uri} permissions that have been granted.
820     * This optimized lookup structure maps from {@link UriPermission#targetUid}
821     * to {@link UriPermission#uri} to {@link UriPermission}.
822     */
823    @GuardedBy("this")
824    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
825            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
826
827    public static class GrantUri {
828        public final int sourceUserId;
829        public final Uri uri;
830        public boolean prefix;
831
832        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
833            this.sourceUserId = sourceUserId;
834            this.uri = uri;
835            this.prefix = prefix;
836        }
837
838        @Override
839        public int hashCode() {
840            int hashCode = 1;
841            hashCode = 31 * hashCode + sourceUserId;
842            hashCode = 31 * hashCode + uri.hashCode();
843            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
844            return hashCode;
845        }
846
847        @Override
848        public boolean equals(Object o) {
849            if (o instanceof GrantUri) {
850                GrantUri other = (GrantUri) o;
851                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
852                        && prefix == other.prefix;
853            }
854            return false;
855        }
856
857        @Override
858        public String toString() {
859            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
860            if (prefix) result += " [prefix]";
861            return result;
862        }
863
864        public String toSafeString() {
865            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
866            if (prefix) result += " [prefix]";
867            return result;
868        }
869
870        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
871            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
872                    ContentProvider.getUriWithoutUserId(uri), false);
873        }
874    }
875
876    CoreSettingsObserver mCoreSettingsObserver;
877
878    /**
879     * Thread-local storage used to carry caller permissions over through
880     * indirect content-provider access.
881     */
882    private class Identity {
883        public final IBinder token;
884        public final int pid;
885        public final int uid;
886
887        Identity(IBinder _token, int _pid, int _uid) {
888            token = _token;
889            pid = _pid;
890            uid = _uid;
891        }
892    }
893
894    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
895
896    /**
897     * All information we have collected about the runtime performance of
898     * any user id that can impact battery performance.
899     */
900    final BatteryStatsService mBatteryStatsService;
901
902    /**
903     * Information about component usage
904     */
905    UsageStatsManagerInternal mUsageStatsService;
906
907    /**
908     * Information about and control over application operations
909     */
910    final AppOpsService mAppOpsService;
911
912    /**
913     * Save recent tasks information across reboots.
914     */
915    final TaskPersister mTaskPersister;
916
917    /**
918     * Current configuration information.  HistoryRecord objects are given
919     * a reference to this object to indicate which configuration they are
920     * currently running in, so this object must be kept immutable.
921     */
922    Configuration mConfiguration = new Configuration();
923
924    /**
925     * Current sequencing integer of the configuration, for skipping old
926     * configurations.
927     */
928    int mConfigurationSeq = 0;
929
930    /**
931     * Hardware-reported OpenGLES version.
932     */
933    final int GL_ES_VERSION;
934
935    /**
936     * List of initialization arguments to pass to all processes when binding applications to them.
937     * For example, references to the commonly used services.
938     */
939    HashMap<String, IBinder> mAppBindArgs;
940
941    /**
942     * Temporary to avoid allocations.  Protected by main lock.
943     */
944    final StringBuilder mStringBuilder = new StringBuilder(256);
945
946    /**
947     * Used to control how we initialize the service.
948     */
949    ComponentName mTopComponent;
950    String mTopAction = Intent.ACTION_MAIN;
951    String mTopData;
952    boolean mProcessesReady = false;
953    boolean mSystemReady = false;
954    boolean mBooting = false;
955    boolean mCallFinishBooting = false;
956    boolean mBootAnimationComplete = false;
957    boolean mWaitingUpdate = false;
958    boolean mDidUpdate = false;
959    boolean mOnBattery = false;
960    boolean mLaunchWarningShown = false;
961
962    Context mContext;
963
964    int mFactoryTest;
965
966    boolean mCheckedForSetup;
967
968    /**
969     * The time at which we will allow normal application switches again,
970     * after a call to {@link #stopAppSwitches()}.
971     */
972    long mAppSwitchesAllowedTime;
973
974    /**
975     * This is set to true after the first switch after mAppSwitchesAllowedTime
976     * is set; any switches after that will clear the time.
977     */
978    boolean mDidAppSwitch;
979
980    /**
981     * Last time (in realtime) at which we checked for power usage.
982     */
983    long mLastPowerCheckRealtime;
984
985    /**
986     * Last time (in uptime) at which we checked for power usage.
987     */
988    long mLastPowerCheckUptime;
989
990    /**
991     * Set while we are wanting to sleep, to prevent any
992     * activities from being started/resumed.
993     */
994    private boolean mSleeping = false;
995
996    /**
997     * Set while we are running a voice interaction.  This overrides
998     * sleeping while it is active.
999     */
1000    private boolean mRunningVoice = false;
1001
1002    /**
1003     * State of external calls telling us if the device is awake or asleep.
1004     */
1005    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1006
1007    static final int LOCK_SCREEN_HIDDEN = 0;
1008    static final int LOCK_SCREEN_LEAVING = 1;
1009    static final int LOCK_SCREEN_SHOWN = 2;
1010    /**
1011     * State of external call telling us if the lock screen is shown.
1012     */
1013    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1014
1015    /**
1016     * Set if we are shutting down the system, similar to sleeping.
1017     */
1018    boolean mShuttingDown = false;
1019
1020    /**
1021     * Current sequence id for oom_adj computation traversal.
1022     */
1023    int mAdjSeq = 0;
1024
1025    /**
1026     * Current sequence id for process LRU updating.
1027     */
1028    int mLruSeq = 0;
1029
1030    /**
1031     * Keep track of the non-cached/empty process we last found, to help
1032     * determine how to distribute cached/empty processes next time.
1033     */
1034    int mNumNonCachedProcs = 0;
1035
1036    /**
1037     * Keep track of the number of cached hidden procs, to balance oom adj
1038     * distribution between those and empty procs.
1039     */
1040    int mNumCachedHiddenProcs = 0;
1041
1042    /**
1043     * Keep track of the number of service processes we last found, to
1044     * determine on the next iteration which should be B services.
1045     */
1046    int mNumServiceProcs = 0;
1047    int mNewNumAServiceProcs = 0;
1048    int mNewNumServiceProcs = 0;
1049
1050    /**
1051     * Allow the current computed overall memory level of the system to go down?
1052     * This is set to false when we are killing processes for reasons other than
1053     * memory management, so that the now smaller process list will not be taken as
1054     * an indication that memory is tighter.
1055     */
1056    boolean mAllowLowerMemLevel = false;
1057
1058    /**
1059     * The last computed memory level, for holding when we are in a state that
1060     * processes are going away for other reasons.
1061     */
1062    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1063
1064    /**
1065     * The last total number of process we have, to determine if changes actually look
1066     * like a shrinking number of process due to lower RAM.
1067     */
1068    int mLastNumProcesses;
1069
1070    /**
1071     * The uptime of the last time we performed idle maintenance.
1072     */
1073    long mLastIdleTime = SystemClock.uptimeMillis();
1074
1075    /**
1076     * Total time spent with RAM that has been added in the past since the last idle time.
1077     */
1078    long mLowRamTimeSinceLastIdle = 0;
1079
1080    /**
1081     * If RAM is currently low, when that horrible situation started.
1082     */
1083    long mLowRamStartTime = 0;
1084
1085    /**
1086     * For reporting to battery stats the current top application.
1087     */
1088    private String mCurResumedPackage = null;
1089    private int mCurResumedUid = -1;
1090
1091    /**
1092     * For reporting to battery stats the apps currently running foreground
1093     * service.  The ProcessMap is package/uid tuples; each of these contain
1094     * an array of the currently foreground processes.
1095     */
1096    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1097            = new ProcessMap<ArrayList<ProcessRecord>>();
1098
1099    /**
1100     * This is set if we had to do a delayed dexopt of an app before launching
1101     * it, to increase the ANR timeouts in that case.
1102     */
1103    boolean mDidDexOpt;
1104
1105    /**
1106     * Set if the systemServer made a call to enterSafeMode.
1107     */
1108    boolean mSafeMode;
1109
1110    /**
1111     * If true, we are running under a test environment so will sample PSS from processes
1112     * much more rapidly to try to collect better data when the tests are rapidly
1113     * running through apps.
1114     */
1115    boolean mTestPssMode = false;
1116
1117    String mDebugApp = null;
1118    boolean mWaitForDebugger = false;
1119    boolean mDebugTransient = false;
1120    String mOrigDebugApp = null;
1121    boolean mOrigWaitForDebugger = false;
1122    boolean mAlwaysFinishActivities = false;
1123    IActivityController mController = null;
1124    String mProfileApp = null;
1125    ProcessRecord mProfileProc = null;
1126    String mProfileFile;
1127    ParcelFileDescriptor mProfileFd;
1128    int mSamplingInterval = 0;
1129    boolean mAutoStopProfiler = false;
1130    int mProfileType = 0;
1131    String mOpenGlTraceApp = null;
1132
1133    final long[] mTmpLong = new long[1];
1134
1135    static class ProcessChangeItem {
1136        static final int CHANGE_ACTIVITIES = 1<<0;
1137        static final int CHANGE_PROCESS_STATE = 1<<1;
1138        int changes;
1139        int uid;
1140        int pid;
1141        int processState;
1142        boolean foregroundActivities;
1143    }
1144
1145    final RemoteCallbackList<IProcessObserver> mProcessObservers
1146            = new RemoteCallbackList<IProcessObserver>();
1147    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1148
1149    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1150            = new ArrayList<ProcessChangeItem>();
1151    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1152            = new ArrayList<ProcessChangeItem>();
1153
1154    /**
1155     * Runtime CPU use collection thread.  This object's lock is used to
1156     * perform synchronization with the thread (notifying it to run).
1157     */
1158    final Thread mProcessCpuThread;
1159
1160    /**
1161     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1162     * Must acquire this object's lock when accessing it.
1163     * NOTE: this lock will be held while doing long operations (trawling
1164     * through all processes in /proc), so it should never be acquired by
1165     * any critical paths such as when holding the main activity manager lock.
1166     */
1167    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1168            MONITOR_THREAD_CPU_USAGE);
1169    final AtomicLong mLastCpuTime = new AtomicLong(0);
1170    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1171
1172    long mLastWriteTime = 0;
1173
1174    /**
1175     * Used to retain an update lock when the foreground activity is in
1176     * immersive mode.
1177     */
1178    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1179
1180    /**
1181     * Set to true after the system has finished booting.
1182     */
1183    boolean mBooted = false;
1184
1185    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1186    int mProcessLimitOverride = -1;
1187
1188    WindowManagerService mWindowManager;
1189
1190    final ActivityThread mSystemThread;
1191
1192    // Holds the current foreground user's id
1193    int mCurrentUserId = 0;
1194    // Holds the target user's id during a user switch
1195    int mTargetUserId = UserHandle.USER_NULL;
1196    // If there are multiple profiles for the current user, their ids are here
1197    // Currently only the primary user can have managed profiles
1198    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1199
1200    /**
1201     * Mapping from each known user ID to the profile group ID it is associated with.
1202     */
1203    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1204
1205    private UserManagerService mUserManager;
1206
1207    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1208        final ProcessRecord mApp;
1209        final int mPid;
1210        final IApplicationThread mAppThread;
1211
1212        AppDeathRecipient(ProcessRecord app, int pid,
1213                IApplicationThread thread) {
1214            if (localLOGV) Slog.v(
1215                TAG, "New death recipient " + this
1216                + " for thread " + thread.asBinder());
1217            mApp = app;
1218            mPid = pid;
1219            mAppThread = thread;
1220        }
1221
1222        @Override
1223        public void binderDied() {
1224            if (localLOGV) Slog.v(
1225                TAG, "Death received in " + this
1226                + " for thread " + mAppThread.asBinder());
1227            synchronized(ActivityManagerService.this) {
1228                appDiedLocked(mApp, mPid, mAppThread);
1229            }
1230        }
1231    }
1232
1233    static final int SHOW_ERROR_MSG = 1;
1234    static final int SHOW_NOT_RESPONDING_MSG = 2;
1235    static final int SHOW_FACTORY_ERROR_MSG = 3;
1236    static final int UPDATE_CONFIGURATION_MSG = 4;
1237    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1238    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1239    static final int SERVICE_TIMEOUT_MSG = 12;
1240    static final int UPDATE_TIME_ZONE = 13;
1241    static final int SHOW_UID_ERROR_MSG = 14;
1242    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1243    static final int PROC_START_TIMEOUT_MSG = 20;
1244    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1245    static final int KILL_APPLICATION_MSG = 22;
1246    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1247    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1248    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1249    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1250    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1251    static final int CLEAR_DNS_CACHE_MSG = 28;
1252    static final int UPDATE_HTTP_PROXY_MSG = 29;
1253    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1254    static final int DISPATCH_PROCESSES_CHANGED = 31;
1255    static final int DISPATCH_PROCESS_DIED = 32;
1256    static final int REPORT_MEM_USAGE_MSG = 33;
1257    static final int REPORT_USER_SWITCH_MSG = 34;
1258    static final int CONTINUE_USER_SWITCH_MSG = 35;
1259    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1260    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1261    static final int PERSIST_URI_GRANTS_MSG = 38;
1262    static final int REQUEST_ALL_PSS_MSG = 39;
1263    static final int START_PROFILES_MSG = 40;
1264    static final int UPDATE_TIME = 41;
1265    static final int SYSTEM_USER_START_MSG = 42;
1266    static final int SYSTEM_USER_CURRENT_MSG = 43;
1267    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1268    static final int FINISH_BOOTING_MSG = 45;
1269    static final int START_USER_SWITCH_MSG = 46;
1270    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1271    static final int DISMISS_DIALOG_MSG = 48;
1272    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1273
1274    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1275    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1276    static final int FIRST_COMPAT_MODE_MSG = 300;
1277    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1278
1279    CompatModeDialog mCompatModeDialog;
1280    long mLastMemUsageReportTime = 0;
1281
1282    /**
1283     * Flag whether the current user is a "monkey", i.e. whether
1284     * the UI is driven by a UI automation tool.
1285     */
1286    private boolean mUserIsMonkey;
1287
1288    /** Flag whether the device has a Recents UI */
1289    boolean mHasRecents;
1290
1291    /** The dimensions of the thumbnails in the Recents UI. */
1292    int mThumbnailWidth;
1293    int mThumbnailHeight;
1294
1295    final ServiceThread mHandlerThread;
1296    final MainHandler mHandler;
1297
1298    final class MainHandler extends Handler {
1299        public MainHandler(Looper looper) {
1300            super(looper, null, true);
1301        }
1302
1303        @Override
1304        public void handleMessage(Message msg) {
1305            switch (msg.what) {
1306            case SHOW_ERROR_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1309                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1310                synchronized (ActivityManagerService.this) {
1311                    ProcessRecord proc = (ProcessRecord)data.get("app");
1312                    AppErrorResult res = (AppErrorResult) data.get("result");
1313                    if (proc != null && proc.crashDialog != null) {
1314                        Slog.e(TAG, "App already has crash dialog: " + proc);
1315                        if (res != null) {
1316                            res.set(0);
1317                        }
1318                        return;
1319                    }
1320                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1321                            >= Process.FIRST_APPLICATION_UID
1322                            && proc.pid != MY_PID);
1323                    for (int userId : mCurrentProfileIds) {
1324                        isBackground &= (proc.userId != userId);
1325                    }
1326                    if (isBackground && !showBackground) {
1327                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1328                        if (res != null) {
1329                            res.set(0);
1330                        }
1331                        return;
1332                    }
1333                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1334                        Dialog d = new AppErrorDialog(mContext,
1335                                ActivityManagerService.this, res, proc);
1336                        d.show();
1337                        proc.crashDialog = d;
1338                    } else {
1339                        // The device is asleep, so just pretend that the user
1340                        // saw a crash dialog and hit "force quit".
1341                        if (res != null) {
1342                            res.set(0);
1343                        }
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_NOT_RESPONDING_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1352                    ProcessRecord proc = (ProcessRecord)data.get("app");
1353                    if (proc != null && proc.anrDialog != null) {
1354                        Slog.e(TAG, "App already has anr dialog: " + proc);
1355                        return;
1356                    }
1357
1358                    Intent intent = new Intent("android.intent.action.ANR");
1359                    if (!mProcessesReady) {
1360                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1361                                | Intent.FLAG_RECEIVER_FOREGROUND);
1362                    }
1363                    broadcastIntentLocked(null, null, intent,
1364                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1365                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1366
1367                    if (mShowDialogs) {
1368                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1369                                mContext, proc, (ActivityRecord)data.get("activity"),
1370                                msg.arg1 != 0);
1371                        d.show();
1372                        proc.anrDialog = d;
1373                    } else {
1374                        // Just kill the app if there is no dialog to be shown.
1375                        killAppAtUsersRequest(proc, null);
1376                    }
1377                }
1378
1379                ensureBootCompleted();
1380            } break;
1381            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1382                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1383                synchronized (ActivityManagerService.this) {
1384                    ProcessRecord proc = (ProcessRecord) data.get("app");
1385                    if (proc == null) {
1386                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1387                        break;
1388                    }
1389                    if (proc.crashDialog != null) {
1390                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1391                        return;
1392                    }
1393                    AppErrorResult res = (AppErrorResult) data.get("result");
1394                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1395                        Dialog d = new StrictModeViolationDialog(mContext,
1396                                ActivityManagerService.this, res, proc);
1397                        d.show();
1398                        proc.crashDialog = d;
1399                    } else {
1400                        // The device is asleep, so just pretend that the user
1401                        // saw a crash dialog and hit "force quit".
1402                        res.set(0);
1403                    }
1404                }
1405                ensureBootCompleted();
1406            } break;
1407            case SHOW_FACTORY_ERROR_MSG: {
1408                Dialog d = new FactoryErrorDialog(
1409                    mContext, msg.getData().getCharSequence("msg"));
1410                d.show();
1411                ensureBootCompleted();
1412            } break;
1413            case UPDATE_CONFIGURATION_MSG: {
1414                final ContentResolver resolver = mContext.getContentResolver();
1415                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1416            } break;
1417            case GC_BACKGROUND_PROCESSES_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    performAppGcsIfAppropriateLocked();
1420                }
1421            } break;
1422            case WAIT_FOR_DEBUGGER_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    ProcessRecord app = (ProcessRecord)msg.obj;
1425                    if (msg.arg1 != 0) {
1426                        if (!app.waitedForDebugger) {
1427                            Dialog d = new AppWaitingForDebuggerDialog(
1428                                    ActivityManagerService.this,
1429                                    mContext, app);
1430                            app.waitDialog = d;
1431                            app.waitedForDebugger = true;
1432                            d.show();
1433                        }
1434                    } else {
1435                        if (app.waitDialog != null) {
1436                            app.waitDialog.dismiss();
1437                            app.waitDialog = null;
1438                        }
1439                    }
1440                }
1441            } break;
1442            case SERVICE_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1448                    return;
1449                }
1450                mServices.serviceTimeout((ProcessRecord)msg.obj);
1451            } break;
1452            case UPDATE_TIME_ZONE: {
1453                synchronized (ActivityManagerService.this) {
1454                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1455                        ProcessRecord r = mLruProcesses.get(i);
1456                        if (r.thread != null) {
1457                            try {
1458                                r.thread.updateTimeZone();
1459                            } catch (RemoteException ex) {
1460                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1461                            }
1462                        }
1463                    }
1464                }
1465            } break;
1466            case CLEAR_DNS_CACHE_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1469                        ProcessRecord r = mLruProcesses.get(i);
1470                        if (r.thread != null) {
1471                            try {
1472                                r.thread.clearDnsCache();
1473                            } catch (RemoteException ex) {
1474                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1475                            }
1476                        }
1477                    }
1478                }
1479            } break;
1480            case UPDATE_HTTP_PROXY_MSG: {
1481                ProxyInfo proxy = (ProxyInfo)msg.obj;
1482                String host = "";
1483                String port = "";
1484                String exclList = "";
1485                Uri pacFileUrl = Uri.EMPTY;
1486                if (proxy != null) {
1487                    host = proxy.getHost();
1488                    port = Integer.toString(proxy.getPort());
1489                    exclList = proxy.getExclusionListAsString();
1490                    pacFileUrl = proxy.getPacFileUrl();
1491                }
1492                synchronized (ActivityManagerService.this) {
1493                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1494                        ProcessRecord r = mLruProcesses.get(i);
1495                        if (r.thread != null) {
1496                            try {
1497                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1498                            } catch (RemoteException ex) {
1499                                Slog.w(TAG, "Failed to update http proxy for: " +
1500                                        r.info.processName);
1501                            }
1502                        }
1503                    }
1504                }
1505            } break;
1506            case SHOW_UID_ERROR_MSG: {
1507                if (mShowDialogs) {
1508                    AlertDialog d = new BaseErrorDialog(mContext);
1509                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1510                    d.setCancelable(false);
1511                    d.setTitle(mContext.getText(R.string.android_system_label));
1512                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1513                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1514                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1515                    d.show();
1516                }
1517            } break;
1518            case SHOW_FINGERPRINT_ERROR_MSG: {
1519                if (mShowDialogs) {
1520                    AlertDialog d = new BaseErrorDialog(mContext);
1521                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1522                    d.setCancelable(false);
1523                    d.setTitle(mContext.getText(R.string.android_system_label));
1524                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1525                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1526                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1527                    d.show();
1528                }
1529            } break;
1530            case PROC_START_TIMEOUT_MSG: {
1531                if (mDidDexOpt) {
1532                    mDidDexOpt = false;
1533                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1534                    nmsg.obj = msg.obj;
1535                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1536                    return;
1537                }
1538                ProcessRecord app = (ProcessRecord)msg.obj;
1539                synchronized (ActivityManagerService.this) {
1540                    processStartTimedOutLocked(app);
1541                }
1542            } break;
1543            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1546                }
1547            } break;
1548            case KILL_APPLICATION_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    int appid = msg.arg1;
1551                    boolean restart = (msg.arg2 == 1);
1552                    Bundle bundle = (Bundle)msg.obj;
1553                    String pkg = bundle.getString("pkg");
1554                    String reason = bundle.getString("reason");
1555                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1556                            false, UserHandle.USER_ALL, reason);
1557                }
1558            } break;
1559            case FINALIZE_PENDING_INTENT_MSG: {
1560                ((PendingIntentRecord)msg.obj).completeFinalize();
1561            } break;
1562            case POST_HEAVY_NOTIFICATION_MSG: {
1563                INotificationManager inm = NotificationManager.getService();
1564                if (inm == null) {
1565                    return;
1566                }
1567
1568                ActivityRecord root = (ActivityRecord)msg.obj;
1569                ProcessRecord process = root.app;
1570                if (process == null) {
1571                    return;
1572                }
1573
1574                try {
1575                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1576                    String text = mContext.getString(R.string.heavy_weight_notification,
1577                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1578                    Notification notification = new Notification();
1579                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1580                    notification.when = 0;
1581                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1582                    notification.tickerText = text;
1583                    notification.defaults = 0; // please be quiet
1584                    notification.sound = null;
1585                    notification.vibrate = null;
1586                    notification.color = mContext.getResources().getColor(
1587                            com.android.internal.R.color.system_notification_accent_color);
1588                    notification.setLatestEventInfo(context, text,
1589                            mContext.getText(R.string.heavy_weight_notification_detail),
1590                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1591                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1592                                    new UserHandle(root.userId)));
1593
1594                    try {
1595                        int[] outId = new int[1];
1596                        inm.enqueueNotificationWithTag("android", "android", null,
1597                                R.string.heavy_weight_notification,
1598                                notification, outId, root.userId);
1599                    } catch (RuntimeException e) {
1600                        Slog.w(ActivityManagerService.TAG,
1601                                "Error showing notification for heavy-weight app", e);
1602                    } catch (RemoteException e) {
1603                    }
1604                } catch (NameNotFoundException e) {
1605                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1606                }
1607            } break;
1608            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1609                INotificationManager inm = NotificationManager.getService();
1610                if (inm == null) {
1611                    return;
1612                }
1613                try {
1614                    inm.cancelNotificationWithTag("android", null,
1615                            R.string.heavy_weight_notification,  msg.arg1);
1616                } catch (RuntimeException e) {
1617                    Slog.w(ActivityManagerService.TAG,
1618                            "Error canceling notification for service", e);
1619                } catch (RemoteException e) {
1620                }
1621            } break;
1622            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    checkExcessivePowerUsageLocked(true);
1625                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1626                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1627                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1628                }
1629            } break;
1630            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1631                synchronized (ActivityManagerService.this) {
1632                    ActivityRecord ar = (ActivityRecord)msg.obj;
1633                    if (mCompatModeDialog != null) {
1634                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1635                                ar.info.applicationInfo.packageName)) {
1636                            return;
1637                        }
1638                        mCompatModeDialog.dismiss();
1639                        mCompatModeDialog = null;
1640                    }
1641                    if (ar != null && false) {
1642                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1643                                ar.packageName)) {
1644                            int mode = mCompatModePackages.computeCompatModeLocked(
1645                                    ar.info.applicationInfo);
1646                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1647                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1648                                mCompatModeDialog = new CompatModeDialog(
1649                                        ActivityManagerService.this, mContext,
1650                                        ar.info.applicationInfo);
1651                                mCompatModeDialog.show();
1652                            }
1653                        }
1654                    }
1655                }
1656                break;
1657            }
1658            case DISPATCH_PROCESSES_CHANGED: {
1659                dispatchProcessesChanged();
1660                break;
1661            }
1662            case DISPATCH_PROCESS_DIED: {
1663                final int pid = msg.arg1;
1664                final int uid = msg.arg2;
1665                dispatchProcessDied(pid, uid);
1666                break;
1667            }
1668            case REPORT_MEM_USAGE_MSG: {
1669                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1670                Thread thread = new Thread() {
1671                    @Override public void run() {
1672                        reportMemUsage(memInfos);
1673                    }
1674                };
1675                thread.start();
1676                break;
1677            }
1678            case START_USER_SWITCH_MSG: {
1679                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1680                break;
1681            }
1682            case REPORT_USER_SWITCH_MSG: {
1683                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1684                break;
1685            }
1686            case CONTINUE_USER_SWITCH_MSG: {
1687                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1688                break;
1689            }
1690            case USER_SWITCH_TIMEOUT_MSG: {
1691                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1692                break;
1693            }
1694            case IMMERSIVE_MODE_LOCK_MSG: {
1695                final boolean nextState = (msg.arg1 != 0);
1696                if (mUpdateLock.isHeld() != nextState) {
1697                    if (DEBUG_IMMERSIVE) {
1698                        final ActivityRecord r = (ActivityRecord) msg.obj;
1699                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1700                    }
1701                    if (nextState) {
1702                        mUpdateLock.acquire();
1703                    } else {
1704                        mUpdateLock.release();
1705                    }
1706                }
1707                break;
1708            }
1709            case PERSIST_URI_GRANTS_MSG: {
1710                writeGrantedUriPermissions();
1711                break;
1712            }
1713            case REQUEST_ALL_PSS_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1716                }
1717                break;
1718            }
1719            case START_PROFILES_MSG: {
1720                synchronized (ActivityManagerService.this) {
1721                    startProfilesLocked();
1722                }
1723                break;
1724            }
1725            case UPDATE_TIME: {
1726                synchronized (ActivityManagerService.this) {
1727                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1728                        ProcessRecord r = mLruProcesses.get(i);
1729                        if (r.thread != null) {
1730                            try {
1731                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1732                            } catch (RemoteException ex) {
1733                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1734                            }
1735                        }
1736                    }
1737                }
1738                break;
1739            }
1740            case SYSTEM_USER_START_MSG: {
1741                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1742                        Integer.toString(msg.arg1), msg.arg1);
1743                mSystemServiceManager.startUser(msg.arg1);
1744                break;
1745            }
1746            case SYSTEM_USER_CURRENT_MSG: {
1747                mBatteryStatsService.noteEvent(
1748                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1749                        Integer.toString(msg.arg2), msg.arg2);
1750                mBatteryStatsService.noteEvent(
1751                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1752                        Integer.toString(msg.arg1), msg.arg1);
1753                mSystemServiceManager.switchUser(msg.arg1);
1754                break;
1755            }
1756            case ENTER_ANIMATION_COMPLETE_MSG: {
1757                synchronized (ActivityManagerService.this) {
1758                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1759                    if (r != null && r.app != null && r.app.thread != null) {
1760                        try {
1761                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1762                        } catch (RemoteException e) {
1763                        }
1764                    }
1765                }
1766                break;
1767            }
1768            case FINISH_BOOTING_MSG: {
1769                if (msg.arg1 != 0) {
1770                    finishBooting();
1771                }
1772                if (msg.arg2 != 0) {
1773                    enableScreenAfterBoot();
1774                }
1775                break;
1776            }
1777            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1778                try {
1779                    Locale l = (Locale) msg.obj;
1780                    IBinder service = ServiceManager.getService("mount");
1781                    IMountService mountService = IMountService.Stub.asInterface(service);
1782                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1783                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1784                } catch (RemoteException e) {
1785                    Log.e(TAG, "Error storing locale for decryption UI", e);
1786                }
1787                break;
1788            }
1789            case DISMISS_DIALOG_MSG: {
1790                final Dialog d = (Dialog) msg.obj;
1791                d.dismiss();
1792                break;
1793            }
1794            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1795                synchronized (ActivityManagerService.this) {
1796                    int i = mTaskStackListeners.beginBroadcast();
1797                    while (i > 0) {
1798                        i--;
1799                        try {
1800                            // Make a one-way callback to the listener
1801                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1802                        } catch (RemoteException e){
1803                            // Handled by the RemoteCallbackList
1804                        }
1805                    }
1806                    mTaskStackListeners.finishBroadcast();
1807                }
1808                break;
1809            }
1810            }
1811        }
1812    };
1813
1814    static final int COLLECT_PSS_BG_MSG = 1;
1815
1816    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1817        @Override
1818        public void handleMessage(Message msg) {
1819            switch (msg.what) {
1820            case COLLECT_PSS_BG_MSG: {
1821                long start = SystemClock.uptimeMillis();
1822                MemInfoReader memInfo = null;
1823                synchronized (ActivityManagerService.this) {
1824                    if (mFullPssPending) {
1825                        mFullPssPending = false;
1826                        memInfo = new MemInfoReader();
1827                    }
1828                }
1829                if (memInfo != null) {
1830                    updateCpuStatsNow();
1831                    long nativeTotalPss = 0;
1832                    synchronized (mProcessCpuTracker) {
1833                        final int N = mProcessCpuTracker.countStats();
1834                        for (int j=0; j<N; j++) {
1835                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1836                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (ActivityManagerService.this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1855                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1856                    }
1857                }
1858
1859                int num = 0;
1860                long[] tmp = new long[1];
1861                do {
1862                    ProcessRecord proc;
1863                    int procState;
1864                    int pid;
1865                    long lastPssTime;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (mPendingPssProcesses.size() <= 0) {
1868                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.remove(0);
1874                        procState = proc.pssProcState;
1875                        lastPssTime = proc.lastPssTime;
1876                        if (proc.thread != null && procState == proc.setProcState
1877                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1878                                        < SystemClock.uptimeMillis()) {
1879                            pid = proc.pid;
1880                        } else {
1881                            proc = null;
1882                            pid = 0;
1883                        }
1884                    }
1885                    if (proc != null) {
1886                        long pss = Debug.getPss(pid, tmp, null);
1887                        synchronized (ActivityManagerService.this) {
1888                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1889                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1890                                num++;
1891                                recordPssSample(proc, procState, pss, tmp[0],
1892                                        SystemClock.uptimeMillis());
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    public void setSystemProcess() {
1903        try {
1904            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1905            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1906            ServiceManager.addService("meminfo", new MemBinder(this));
1907            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1908            ServiceManager.addService("dbinfo", new DbBinder(this));
1909            if (MONITOR_CPU_USAGE) {
1910                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1911            }
1912            ServiceManager.addService("permission", new PermissionController(this));
1913
1914            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1915                    "android", STOCK_PM_FLAGS);
1916            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1917
1918            synchronized (this) {
1919                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1920                app.persistent = true;
1921                app.pid = MY_PID;
1922                app.maxAdj = ProcessList.SYSTEM_ADJ;
1923                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1924                mProcessNames.put(app.processName, app.uid, app);
1925                synchronized (mPidsSelfLocked) {
1926                    mPidsSelfLocked.put(app.pid, app);
1927                }
1928                updateLruProcessLocked(app, false, null);
1929                updateOomAdjLocked();
1930            }
1931        } catch (PackageManager.NameNotFoundException e) {
1932            throw new RuntimeException(
1933                    "Unable to find android system package", e);
1934        }
1935    }
1936
1937    public void setWindowManager(WindowManagerService wm) {
1938        mWindowManager = wm;
1939        mStackSupervisor.setWindowManager(wm);
1940    }
1941
1942    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1943        mUsageStatsService = usageStatsManager;
1944    }
1945
1946    public void startObservingNativeCrashes() {
1947        final NativeCrashListener ncl = new NativeCrashListener(this);
1948        ncl.start();
1949    }
1950
1951    public IAppOpsService getAppOpsService() {
1952        return mAppOpsService;
1953    }
1954
1955    static class MemBinder extends Binder {
1956        ActivityManagerService mActivityManagerService;
1957        MemBinder(ActivityManagerService activityManagerService) {
1958            mActivityManagerService = activityManagerService;
1959        }
1960
1961        @Override
1962        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1963            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1964                    != PackageManager.PERMISSION_GRANTED) {
1965                pw.println("Permission Denial: can't dump meminfo from from pid="
1966                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1967                        + " without permission " + android.Manifest.permission.DUMP);
1968                return;
1969            }
1970
1971            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1972        }
1973    }
1974
1975    static class GraphicsBinder extends Binder {
1976        ActivityManagerService mActivityManagerService;
1977        GraphicsBinder(ActivityManagerService activityManagerService) {
1978            mActivityManagerService = activityManagerService;
1979        }
1980
1981        @Override
1982        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1983            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1984                    != PackageManager.PERMISSION_GRANTED) {
1985                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1986                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1987                        + " without permission " + android.Manifest.permission.DUMP);
1988                return;
1989            }
1990
1991            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1992        }
1993    }
1994
1995    static class DbBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        DbBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump dbinfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpDbInfo(fd, pw, args);
2012        }
2013    }
2014
2015    static class CpuBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        CpuBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            synchronized (mActivityManagerService.mProcessCpuTracker) {
2032                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2033                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2034                        SystemClock.uptimeMillis()));
2035            }
2036        }
2037    }
2038
2039    public static final class Lifecycle extends SystemService {
2040        private final ActivityManagerService mService;
2041
2042        public Lifecycle(Context context) {
2043            super(context);
2044            mService = new ActivityManagerService(context);
2045        }
2046
2047        @Override
2048        public void onStart() {
2049            mService.start();
2050        }
2051
2052        public ActivityManagerService getService() {
2053            return mService;
2054        }
2055    }
2056
2057    // Note: This method is invoked on the main thread but may need to attach various
2058    // handlers to other threads.  So take care to be explicit about the looper.
2059    public ActivityManagerService(Context systemContext) {
2060        mContext = systemContext;
2061        mFactoryTest = FactoryTest.getMode();
2062        mSystemThread = ActivityThread.currentActivityThread();
2063
2064        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2065
2066        mHandlerThread = new ServiceThread(TAG,
2067                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2068        mHandlerThread.start();
2069        mHandler = new MainHandler(mHandlerThread.getLooper());
2070
2071        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2072                "foreground", BROADCAST_FG_TIMEOUT, false);
2073        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2074                "background", BROADCAST_BG_TIMEOUT, true);
2075        mBroadcastQueues[0] = mFgBroadcastQueue;
2076        mBroadcastQueues[1] = mBgBroadcastQueue;
2077
2078        mServices = new ActiveServices(this);
2079        mProviderMap = new ProviderMap(this);
2080
2081        // TODO: Move creation of battery stats service outside of activity manager service.
2082        File dataDir = Environment.getDataDirectory();
2083        File systemDir = new File(dataDir, "system");
2084        systemDir.mkdirs();
2085        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2086        mBatteryStatsService.getActiveStatistics().readLocked();
2087        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2088        mOnBattery = DEBUG_POWER ? true
2089                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2090        mBatteryStatsService.getActiveStatistics().setCallback(this);
2091
2092        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2093
2094        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2095
2096        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2097
2098        // User 0 is the first and only user that runs at boot.
2099        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2100        mUserLru.add(Integer.valueOf(0));
2101        updateStartedUserArrayLocked();
2102
2103        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2104            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2105
2106        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2107
2108        mConfiguration.setToDefaults();
2109        mConfiguration.setLocale(Locale.getDefault());
2110
2111        mConfigurationSeq = mConfiguration.seq = 1;
2112        mProcessCpuTracker.init();
2113
2114        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2115        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2116        mStackSupervisor = new ActivityStackSupervisor(this);
2117        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2118
2119        mProcessCpuThread = new Thread("CpuTracker") {
2120            @Override
2121            public void run() {
2122                while (true) {
2123                    try {
2124                        try {
2125                            synchronized(this) {
2126                                final long now = SystemClock.uptimeMillis();
2127                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2128                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2129                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2130                                //        + ", write delay=" + nextWriteDelay);
2131                                if (nextWriteDelay < nextCpuDelay) {
2132                                    nextCpuDelay = nextWriteDelay;
2133                                }
2134                                if (nextCpuDelay > 0) {
2135                                    mProcessCpuMutexFree.set(true);
2136                                    this.wait(nextCpuDelay);
2137                                }
2138                            }
2139                        } catch (InterruptedException e) {
2140                        }
2141                        updateCpuStatsNow();
2142                    } catch (Exception e) {
2143                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2144                    }
2145                }
2146            }
2147        };
2148
2149        Watchdog.getInstance().addMonitor(this);
2150        Watchdog.getInstance().addThread(mHandler);
2151    }
2152
2153    public void setSystemServiceManager(SystemServiceManager mgr) {
2154        mSystemServiceManager = mgr;
2155    }
2156
2157    public void setInstaller(Installer installer) {
2158        mInstaller = installer;
2159    }
2160
2161    private void start() {
2162        Process.removeAllProcessGroups();
2163        mProcessCpuThread.start();
2164
2165        mBatteryStatsService.publish(mContext);
2166        mAppOpsService.publish(mContext);
2167        Slog.d("AppOps", "AppOpsService published");
2168        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2169    }
2170
2171    public void initPowerManagement() {
2172        mStackSupervisor.initPowerManagement();
2173        mBatteryStatsService.initPowerManagement();
2174    }
2175
2176    @Override
2177    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2178            throws RemoteException {
2179        if (code == SYSPROPS_TRANSACTION) {
2180            // We need to tell all apps about the system property change.
2181            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2182            synchronized(this) {
2183                final int NP = mProcessNames.getMap().size();
2184                for (int ip=0; ip<NP; ip++) {
2185                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2186                    final int NA = apps.size();
2187                    for (int ia=0; ia<NA; ia++) {
2188                        ProcessRecord app = apps.valueAt(ia);
2189                        if (app.thread != null) {
2190                            procs.add(app.thread.asBinder());
2191                        }
2192                    }
2193                }
2194            }
2195
2196            int N = procs.size();
2197            for (int i=0; i<N; i++) {
2198                Parcel data2 = Parcel.obtain();
2199                try {
2200                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2201                } catch (RemoteException e) {
2202                }
2203                data2.recycle();
2204            }
2205        }
2206        try {
2207            return super.onTransact(code, data, reply, flags);
2208        } catch (RuntimeException e) {
2209            // The activity manager only throws security exceptions, so let's
2210            // log all others.
2211            if (!(e instanceof SecurityException)) {
2212                Slog.wtf(TAG, "Activity Manager Crash", e);
2213            }
2214            throw e;
2215        }
2216    }
2217
2218    void updateCpuStats() {
2219        final long now = SystemClock.uptimeMillis();
2220        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2221            return;
2222        }
2223        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2224            synchronized (mProcessCpuThread) {
2225                mProcessCpuThread.notify();
2226            }
2227        }
2228    }
2229
2230    void updateCpuStatsNow() {
2231        synchronized (mProcessCpuTracker) {
2232            mProcessCpuMutexFree.set(false);
2233            final long now = SystemClock.uptimeMillis();
2234            boolean haveNewCpuStats = false;
2235
2236            if (MONITOR_CPU_USAGE &&
2237                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2238                mLastCpuTime.set(now);
2239                haveNewCpuStats = true;
2240                mProcessCpuTracker.update();
2241                //Slog.i(TAG, mProcessCpu.printCurrentState());
2242                //Slog.i(TAG, "Total CPU usage: "
2243                //        + mProcessCpu.getTotalCpuPercent() + "%");
2244
2245                // Slog the cpu usage if the property is set.
2246                if ("true".equals(SystemProperties.get("events.cpu"))) {
2247                    int user = mProcessCpuTracker.getLastUserTime();
2248                    int system = mProcessCpuTracker.getLastSystemTime();
2249                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2250                    int irq = mProcessCpuTracker.getLastIrqTime();
2251                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2252                    int idle = mProcessCpuTracker.getLastIdleTime();
2253
2254                    int total = user + system + iowait + irq + softIrq + idle;
2255                    if (total == 0) total = 1;
2256
2257                    EventLog.writeEvent(EventLogTags.CPU,
2258                            ((user+system+iowait+irq+softIrq) * 100) / total,
2259                            (user * 100) / total,
2260                            (system * 100) / total,
2261                            (iowait * 100) / total,
2262                            (irq * 100) / total,
2263                            (softIrq * 100) / total);
2264                }
2265            }
2266
2267            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2268            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2269            synchronized(bstats) {
2270                synchronized(mPidsSelfLocked) {
2271                    if (haveNewCpuStats) {
2272                        if (mOnBattery) {
2273                            int perc = bstats.startAddingCpuLocked();
2274                            int totalUTime = 0;
2275                            int totalSTime = 0;
2276                            final int N = mProcessCpuTracker.countStats();
2277                            for (int i=0; i<N; i++) {
2278                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2279                                if (!st.working) {
2280                                    continue;
2281                                }
2282                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2283                                int otherUTime = (st.rel_utime*perc)/100;
2284                                int otherSTime = (st.rel_stime*perc)/100;
2285                                totalUTime += otherUTime;
2286                                totalSTime += otherSTime;
2287                                if (pr != null) {
2288                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2289                                    if (ps == null || !ps.isActive()) {
2290                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2291                                                pr.info.uid, pr.processName);
2292                                    }
2293                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2294                                            st.rel_stime-otherSTime);
2295                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2296                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2297                                } else {
2298                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2299                                    if (ps == null || !ps.isActive()) {
2300                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2301                                                bstats.mapUid(st.uid), st.name);
2302                                    }
2303                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2304                                            st.rel_stime-otherSTime);
2305                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2306                                }
2307                            }
2308                            bstats.finishAddingCpuLocked(perc, totalUTime,
2309                                    totalSTime, cpuSpeedTimes);
2310                        }
2311                    }
2312                }
2313
2314                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2315                    mLastWriteTime = now;
2316                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2317                }
2318            }
2319        }
2320    }
2321
2322    @Override
2323    public void batteryNeedsCpuUpdate() {
2324        updateCpuStatsNow();
2325    }
2326
2327    @Override
2328    public void batteryPowerChanged(boolean onBattery) {
2329        // When plugging in, update the CPU stats first before changing
2330        // the plug state.
2331        updateCpuStatsNow();
2332        synchronized (this) {
2333            synchronized(mPidsSelfLocked) {
2334                mOnBattery = DEBUG_POWER ? true : onBattery;
2335            }
2336        }
2337    }
2338
2339    /**
2340     * Initialize the application bind args. These are passed to each
2341     * process when the bindApplication() IPC is sent to the process. They're
2342     * lazily setup to make sure the services are running when they're asked for.
2343     */
2344    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2345        if (mAppBindArgs == null) {
2346            mAppBindArgs = new HashMap<>();
2347
2348            // Isolated processes won't get this optimization, so that we don't
2349            // violate the rules about which services they have access to.
2350            if (!isolated) {
2351                // Setup the application init args
2352                mAppBindArgs.put("package", ServiceManager.getService("package"));
2353                mAppBindArgs.put("window", ServiceManager.getService("window"));
2354                mAppBindArgs.put(Context.ALARM_SERVICE,
2355                        ServiceManager.getService(Context.ALARM_SERVICE));
2356            }
2357        }
2358        return mAppBindArgs;
2359    }
2360
2361    final void setFocusedActivityLocked(ActivityRecord r) {
2362        if (mFocusedActivity != r) {
2363            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2364            mFocusedActivity = r;
2365            if (r.task != null && r.task.voiceInteractor != null) {
2366                startRunningVoiceLocked();
2367            } else {
2368                finishRunningVoiceLocked();
2369            }
2370            mStackSupervisor.setFocusedStack(r);
2371            if (r != null) {
2372                mWindowManager.setFocusedApp(r.appToken, true);
2373            }
2374            applyUpdateLockStateLocked(r);
2375        }
2376    }
2377
2378    final void clearFocusedActivity(ActivityRecord r) {
2379        if (mFocusedActivity == r) {
2380            mFocusedActivity = null;
2381        }
2382    }
2383
2384    @Override
2385    public void setFocusedStack(int stackId) {
2386        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2387        synchronized (ActivityManagerService.this) {
2388            ActivityStack stack = mStackSupervisor.getStack(stackId);
2389            if (stack != null) {
2390                ActivityRecord r = stack.topRunningActivityLocked(null);
2391                if (r != null) {
2392                    setFocusedActivityLocked(r);
2393                }
2394            }
2395        }
2396    }
2397
2398    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2399    @Override
2400    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2401        synchronized (ActivityManagerService.this) {
2402            if (listener != null) {
2403                mTaskStackListeners.register(listener);
2404            }
2405        }
2406    }
2407
2408    @Override
2409    public void notifyActivityDrawn(IBinder token) {
2410        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2411        synchronized (this) {
2412            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2413            if (r != null) {
2414                r.task.stack.notifyActivityDrawnLocked(r);
2415            }
2416        }
2417    }
2418
2419    final void applyUpdateLockStateLocked(ActivityRecord r) {
2420        // Modifications to the UpdateLock state are done on our handler, outside
2421        // the activity manager's locks.  The new state is determined based on the
2422        // state *now* of the relevant activity record.  The object is passed to
2423        // the handler solely for logging detail, not to be consulted/modified.
2424        final boolean nextState = r != null && r.immersive;
2425        mHandler.sendMessage(
2426                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2427    }
2428
2429    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2430        Message msg = Message.obtain();
2431        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2432        msg.obj = r.task.askedCompatMode ? null : r;
2433        mHandler.sendMessage(msg);
2434    }
2435
2436    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2437            String what, Object obj, ProcessRecord srcApp) {
2438        app.lastActivityTime = now;
2439
2440        if (app.activities.size() > 0) {
2441            // Don't want to touch dependent processes that are hosting activities.
2442            return index;
2443        }
2444
2445        int lrui = mLruProcesses.lastIndexOf(app);
2446        if (lrui < 0) {
2447            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2448                    + what + " " + obj + " from " + srcApp);
2449            return index;
2450        }
2451
2452        if (lrui >= index) {
2453            // Don't want to cause this to move dependent processes *back* in the
2454            // list as if they were less frequently used.
2455            return index;
2456        }
2457
2458        if (lrui >= mLruProcessActivityStart) {
2459            // Don't want to touch dependent processes that are hosting activities.
2460            return index;
2461        }
2462
2463        mLruProcesses.remove(lrui);
2464        if (index > 0) {
2465            index--;
2466        }
2467        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2468                + " in LRU list: " + app);
2469        mLruProcesses.add(index, app);
2470        return index;
2471    }
2472
2473    final void removeLruProcessLocked(ProcessRecord app) {
2474        int lrui = mLruProcesses.lastIndexOf(app);
2475        if (lrui >= 0) {
2476            if (!app.killed) {
2477                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2478                Process.killProcessQuiet(app.pid);
2479                Process.killProcessGroup(app.info.uid, app.pid);
2480            }
2481            if (lrui <= mLruProcessActivityStart) {
2482                mLruProcessActivityStart--;
2483            }
2484            if (lrui <= mLruProcessServiceStart) {
2485                mLruProcessServiceStart--;
2486            }
2487            mLruProcesses.remove(lrui);
2488        }
2489    }
2490
2491    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2492            ProcessRecord client) {
2493        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2494                || app.treatLikeActivity;
2495        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2496        if (!activityChange && hasActivity) {
2497            // The process has activities, so we are only allowing activity-based adjustments
2498            // to move it.  It should be kept in the front of the list with other
2499            // processes that have activities, and we don't want those to change their
2500            // order except due to activity operations.
2501            return;
2502        }
2503
2504        mLruSeq++;
2505        final long now = SystemClock.uptimeMillis();
2506        app.lastActivityTime = now;
2507
2508        // First a quick reject: if the app is already at the position we will
2509        // put it, then there is nothing to do.
2510        if (hasActivity) {
2511            final int N = mLruProcesses.size();
2512            if (N > 0 && mLruProcesses.get(N-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2514                return;
2515            }
2516        } else {
2517            if (mLruProcessServiceStart > 0
2518                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2519                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2520                return;
2521            }
2522        }
2523
2524        int lrui = mLruProcesses.lastIndexOf(app);
2525
2526        if (app.persistent && lrui >= 0) {
2527            // We don't care about the position of persistent processes, as long as
2528            // they are in the list.
2529            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2530            return;
2531        }
2532
2533        /* In progress: compute new position first, so we can avoid doing work
2534           if the process is not actually going to move.  Not yet working.
2535        int addIndex;
2536        int nextIndex;
2537        boolean inActivity = false, inService = false;
2538        if (hasActivity) {
2539            // Process has activities, put it at the very tipsy-top.
2540            addIndex = mLruProcesses.size();
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543        } else if (hasService) {
2544            // Process has services, put it at the top of the service list.
2545            addIndex = mLruProcessActivityStart;
2546            nextIndex = mLruProcessServiceStart;
2547            inActivity = true;
2548            inService = true;
2549        } else  {
2550            // Process not otherwise of interest, it goes to the top of the non-service area.
2551            addIndex = mLruProcessServiceStart;
2552            if (client != null) {
2553                int clientIndex = mLruProcesses.lastIndexOf(client);
2554                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2555                        + app);
2556                if (clientIndex >= 0 && addIndex > clientIndex) {
2557                    addIndex = clientIndex;
2558                }
2559            }
2560            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2561        }
2562
2563        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2564                + mLruProcessActivityStart + "): " + app);
2565        */
2566
2567        if (lrui >= 0) {
2568            if (lrui < mLruProcessActivityStart) {
2569                mLruProcessActivityStart--;
2570            }
2571            if (lrui < mLruProcessServiceStart) {
2572                mLruProcessServiceStart--;
2573            }
2574            /*
2575            if (addIndex > lrui) {
2576                addIndex--;
2577            }
2578            if (nextIndex > lrui) {
2579                nextIndex--;
2580            }
2581            */
2582            mLruProcesses.remove(lrui);
2583        }
2584
2585        /*
2586        mLruProcesses.add(addIndex, app);
2587        if (inActivity) {
2588            mLruProcessActivityStart++;
2589        }
2590        if (inService) {
2591            mLruProcessActivityStart++;
2592        }
2593        */
2594
2595        int nextIndex;
2596        if (hasActivity) {
2597            final int N = mLruProcesses.size();
2598            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2599                // Process doesn't have activities, but has clients with
2600                // activities...  move it up, but one below the top (the top
2601                // should always have a real activity).
2602                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2603                mLruProcesses.add(N-1, app);
2604                // To keep it from spamming the LRU list (by making a bunch of clients),
2605                // we will push down any other entries owned by the app.
2606                final int uid = app.info.uid;
2607                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2608                    ProcessRecord subProc = mLruProcesses.get(i);
2609                    if (subProc.info.uid == uid) {
2610                        // We want to push this one down the list.  If the process after
2611                        // it is for the same uid, however, don't do so, because we don't
2612                        // want them internally to be re-ordered.
2613                        if (mLruProcesses.get(i-1).info.uid != uid) {
2614                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2615                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2616                            ProcessRecord tmp = mLruProcesses.get(i);
2617                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2618                            mLruProcesses.set(i-1, tmp);
2619                            i--;
2620                        }
2621                    } else {
2622                        // A gap, we can stop here.
2623                        break;
2624                    }
2625                }
2626            } else {
2627                // Process has activities, put it at the very tipsy-top.
2628                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2629                mLruProcesses.add(app);
2630            }
2631            nextIndex = mLruProcessServiceStart;
2632        } else if (hasService) {
2633            // Process has services, put it at the top of the service list.
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2635            mLruProcesses.add(mLruProcessActivityStart, app);
2636            nextIndex = mLruProcessServiceStart;
2637            mLruProcessActivityStart++;
2638        } else  {
2639            // Process not otherwise of interest, it goes to the top of the non-service area.
2640            int index = mLruProcessServiceStart;
2641            if (client != null) {
2642                // If there is a client, don't allow the process to be moved up higher
2643                // in the list than that client.
2644                int clientIndex = mLruProcesses.lastIndexOf(client);
2645                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2646                        + " when updating " + app);
2647                if (clientIndex <= lrui) {
2648                    // Don't allow the client index restriction to push it down farther in the
2649                    // list than it already is.
2650                    clientIndex = lrui;
2651                }
2652                if (clientIndex >= 0 && index > clientIndex) {
2653                    index = clientIndex;
2654                }
2655            }
2656            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2657            mLruProcesses.add(index, app);
2658            nextIndex = index-1;
2659            mLruProcessActivityStart++;
2660            mLruProcessServiceStart++;
2661        }
2662
2663        // If the app is currently using a content provider or service,
2664        // bump those processes as well.
2665        for (int j=app.connections.size()-1; j>=0; j--) {
2666            ConnectionRecord cr = app.connections.valueAt(j);
2667            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2668                    && cr.binding.service.app != null
2669                    && cr.binding.service.app.lruSeq != mLruSeq
2670                    && !cr.binding.service.app.persistent) {
2671                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2672                        "service connection", cr, app);
2673            }
2674        }
2675        for (int j=app.conProviders.size()-1; j>=0; j--) {
2676            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2677            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2679                        "provider reference", cpr, app);
2680            }
2681        }
2682    }
2683
2684    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2685        if (uid == Process.SYSTEM_UID) {
2686            // The system gets to run in any process.  If there are multiple
2687            // processes with the same uid, just pick the first (this
2688            // should never happen).
2689            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2690            if (procs == null) return null;
2691            final int N = procs.size();
2692            for (int i = 0; i < N; i++) {
2693                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2694            }
2695        }
2696        ProcessRecord proc = mProcessNames.get(processName, uid);
2697        if (false && proc != null && !keepIfLarge
2698                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2699                && proc.lastCachedPss >= 4000) {
2700            // Turn this condition on to cause killing to happen regularly, for testing.
2701            if (proc.baseProcessTracker != null) {
2702                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2703            }
2704            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2705        } else if (proc != null && !keepIfLarge
2706                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2707                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2708            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2709            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2710                if (proc.baseProcessTracker != null) {
2711                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2712                }
2713                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2714            }
2715        }
2716        return proc;
2717    }
2718
2719    void ensurePackageDexOpt(String packageName) {
2720        IPackageManager pm = AppGlobals.getPackageManager();
2721        try {
2722            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2723                mDidDexOpt = true;
2724            }
2725        } catch (RemoteException e) {
2726        }
2727    }
2728
2729    boolean isNextTransitionForward() {
2730        int transit = mWindowManager.getPendingAppTransition();
2731        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2732                || transit == AppTransition.TRANSIT_TASK_OPEN
2733                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2734    }
2735
2736    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2737            String processName, String abiOverride, int uid, Runnable crashHandler) {
2738        synchronized(this) {
2739            ApplicationInfo info = new ApplicationInfo();
2740            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2741            // For isolated processes, the former contains the parent's uid and the latter the
2742            // actual uid of the isolated process.
2743            // In the special case introduced by this method (which is, starting an isolated
2744            // process directly from the SystemServer without an actual parent app process) the
2745            // closest thing to a parent's uid is SYSTEM_UID.
2746            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2747            // the |isolated| logic in the ProcessRecord constructor.
2748            info.uid = Process.SYSTEM_UID;
2749            info.processName = processName;
2750            info.className = entryPoint;
2751            info.packageName = "android";
2752            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2753                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2754                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2755                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2756                    crashHandler);
2757            return proc != null ? proc.pid : 0;
2758        }
2759    }
2760
2761    final ProcessRecord startProcessLocked(String processName,
2762            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2763            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2764            boolean isolated, boolean keepIfLarge) {
2765        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2766                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2767                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2768                null /* crashHandler */);
2769    }
2770
2771    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2772            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2773            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2774            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2775        long startTime = SystemClock.elapsedRealtime();
2776        ProcessRecord app;
2777        if (!isolated) {
2778            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2779            checkTime(startTime, "startProcess: after getProcessRecord");
2780        } else {
2781            // If this is an isolated process, it can't re-use an existing process.
2782            app = null;
2783        }
2784        // We don't have to do anything more if:
2785        // (1) There is an existing application record; and
2786        // (2) The caller doesn't think it is dead, OR there is no thread
2787        //     object attached to it so we know it couldn't have crashed; and
2788        // (3) There is a pid assigned to it, so it is either starting or
2789        //     already running.
2790        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2791                + " app=" + app + " knownToBeDead=" + knownToBeDead
2792                + " thread=" + (app != null ? app.thread : null)
2793                + " pid=" + (app != null ? app.pid : -1));
2794        if (app != null && app.pid > 0) {
2795            if (!knownToBeDead || app.thread == null) {
2796                // We already have the app running, or are waiting for it to
2797                // come up (we have a pid but not yet its thread), so keep it.
2798                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2799                // If this is a new package in the process, add the package to the list
2800                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2801                checkTime(startTime, "startProcess: done, added package to proc");
2802                return app;
2803            }
2804
2805            // An application record is attached to a previous process,
2806            // clean it up now.
2807            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2808            checkTime(startTime, "startProcess: bad proc running, killing");
2809            Process.killProcessGroup(app.info.uid, app.pid);
2810            handleAppDiedLocked(app, true, true);
2811            checkTime(startTime, "startProcess: done killing old proc");
2812        }
2813
2814        String hostingNameStr = hostingName != null
2815                ? hostingName.flattenToShortString() : null;
2816
2817        if (!isolated) {
2818            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2819                // If we are in the background, then check to see if this process
2820                // is bad.  If so, we will just silently fail.
2821                if (mBadProcesses.get(info.processName, info.uid) != null) {
2822                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2823                            + "/" + info.processName);
2824                    return null;
2825                }
2826            } else {
2827                // When the user is explicitly starting a process, then clear its
2828                // crash count so that we won't make it bad until they see at
2829                // least one crash dialog again, and make the process good again
2830                // if it had been bad.
2831                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2832                        + "/" + info.processName);
2833                mProcessCrashTimes.remove(info.processName, info.uid);
2834                if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2836                            UserHandle.getUserId(info.uid), info.uid,
2837                            info.processName);
2838                    mBadProcesses.remove(info.processName, info.uid);
2839                    if (app != null) {
2840                        app.bad = false;
2841                    }
2842                }
2843            }
2844        }
2845
2846        if (app == null) {
2847            checkTime(startTime, "startProcess: creating new process record");
2848            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2849            if (app == null) {
2850                Slog.w(TAG, "Failed making new process record for "
2851                        + processName + "/" + info.uid + " isolated=" + isolated);
2852                return null;
2853            }
2854            app.crashHandler = crashHandler;
2855            mProcessNames.put(processName, app.uid, app);
2856            if (isolated) {
2857                mIsolatedProcesses.put(app.uid, app);
2858            }
2859            checkTime(startTime, "startProcess: done creating new process record");
2860        } else {
2861            // If this is a new package in the process, add the package to the list
2862            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2863            checkTime(startTime, "startProcess: added package to existing proc");
2864        }
2865
2866        // If the system is not ready yet, then hold off on starting this
2867        // process until it is.
2868        if (!mProcessesReady
2869                && !isAllowedWhileBooting(info)
2870                && !allowWhileBooting) {
2871            if (!mProcessesOnHold.contains(app)) {
2872                mProcessesOnHold.add(app);
2873            }
2874            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2875            checkTime(startTime, "startProcess: returning with proc on hold");
2876            return app;
2877        }
2878
2879        checkTime(startTime, "startProcess: stepping in to startProcess");
2880        startProcessLocked(
2881                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2882        checkTime(startTime, "startProcess: done starting proc!");
2883        return (app.pid != 0) ? app : null;
2884    }
2885
2886    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2887        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2888    }
2889
2890    private final void startProcessLocked(ProcessRecord app,
2891            String hostingType, String hostingNameStr) {
2892        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2893                null /* entryPoint */, null /* entryPointArgs */);
2894    }
2895
2896    private final void startProcessLocked(ProcessRecord app, String hostingType,
2897            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2898        long startTime = SystemClock.elapsedRealtime();
2899        if (app.pid > 0 && app.pid != MY_PID) {
2900            checkTime(startTime, "startProcess: removing from pids map");
2901            synchronized (mPidsSelfLocked) {
2902                mPidsSelfLocked.remove(app.pid);
2903                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2904            }
2905            checkTime(startTime, "startProcess: done removing from pids map");
2906            app.setPid(0);
2907        }
2908
2909        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2910                "startProcessLocked removing on hold: " + app);
2911        mProcessesOnHold.remove(app);
2912
2913        checkTime(startTime, "startProcess: starting to update cpu stats");
2914        updateCpuStats();
2915        checkTime(startTime, "startProcess: done updating cpu stats");
2916
2917        try {
2918            int uid = app.uid;
2919
2920            int[] gids = null;
2921            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2922            if (!app.isolated) {
2923                int[] permGids = null;
2924                try {
2925                    checkTime(startTime, "startProcess: getting gids from package manager");
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        checkTime(startTime, "startProcess: checking external storage perm");
2931                        if (pm.checkPermission(
2932                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2933                                app.info.packageName) == PERMISSION_GRANTED) {
2934                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2935                        } else {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2937                        }
2938                    }
2939                } catch (PackageManager.NameNotFoundException e) {
2940                    Slog.w(TAG, "Unable to retrieve gids", e);
2941                }
2942
2943                /*
2944                 * Add shared application and profile GIDs so applications can share some
2945                 * resources like shared libraries and access user-wide resources
2946                 */
2947                if (permGids == null) {
2948                    gids = new int[2];
2949                } else {
2950                    gids = new int[permGids.length + 2];
2951                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2952                }
2953                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2954                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2955            }
2956            checkTime(startTime, "startProcess: building args");
2957            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2958                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2959                        && mTopComponent != null
2960                        && app.processName.equals(mTopComponent.getPackageName())) {
2961                    uid = 0;
2962                }
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2964                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2965                    uid = 0;
2966                }
2967            }
2968            int debugFlags = 0;
2969            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2970                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2971                // Also turn on CheckJNI for debuggable apps. It's quite
2972                // awkward to turn on otherwise.
2973                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2974            }
2975            // Run the app in safe mode if its manifest requests so or the
2976            // system is booted in safe mode.
2977            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2978                mSafeMode == true) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.assert"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2989            }
2990
2991            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2992            if (requiredAbi == null) {
2993                requiredAbi = Build.SUPPORTED_ABIS[0];
2994            }
2995
2996            String instructionSet = null;
2997            if (app.info.primaryCpuAbi != null) {
2998                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2999            }
3000
3001            // Start the process.  It will either succeed and return a result containing
3002            // the PID of the new process, or else throw a RuntimeException.
3003            boolean isActivityProcess = (entryPoint == null);
3004            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3005            checkTime(startTime, "startProcess: asking zygote to start proc");
3006            Process.ProcessStartResult startResult = Process.start(entryPoint,
3007                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3008                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3009                    app.info.dataDir, entryPointArgs);
3010            checkTime(startTime, "startProcess: returned from zygote!");
3011
3012            if (app.isolated) {
3013                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3014            }
3015            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3016            checkTime(startTime, "startProcess: done updating battery stats");
3017
3018            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3019                    UserHandle.getUserId(uid), startResult.pid, uid,
3020                    app.processName, hostingType,
3021                    hostingNameStr != null ? hostingNameStr : "");
3022
3023            if (app.persistent) {
3024                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3025            }
3026
3027            checkTime(startTime, "startProcess: building log message");
3028            StringBuilder buf = mStringBuilder;
3029            buf.setLength(0);
3030            buf.append("Start proc ");
3031            buf.append(app.processName);
3032            if (!isActivityProcess) {
3033                buf.append(" [");
3034                buf.append(entryPoint);
3035                buf.append("]");
3036            }
3037            buf.append(" for ");
3038            buf.append(hostingType);
3039            if (hostingNameStr != null) {
3040                buf.append(" ");
3041                buf.append(hostingNameStr);
3042            }
3043            buf.append(": pid=");
3044            buf.append(startResult.pid);
3045            buf.append(" uid=");
3046            buf.append(uid);
3047            buf.append(" gids={");
3048            if (gids != null) {
3049                for (int gi=0; gi<gids.length; gi++) {
3050                    if (gi != 0) buf.append(", ");
3051                    buf.append(gids[gi]);
3052
3053                }
3054            }
3055            buf.append("}");
3056            if (requiredAbi != null) {
3057                buf.append(" abi=");
3058                buf.append(requiredAbi);
3059            }
3060            Slog.i(TAG, buf.toString());
3061            app.setPid(startResult.pid);
3062            app.usingWrapper = startResult.usingWrapper;
3063            app.removed = false;
3064            app.killed = false;
3065            app.killedByAm = false;
3066            checkTime(startTime, "startProcess: starting to update pids map");
3067            synchronized (mPidsSelfLocked) {
3068                this.mPidsSelfLocked.put(startResult.pid, app);
3069                if (isActivityProcess) {
3070                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3071                    msg.obj = app;
3072                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3073                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3074                }
3075            }
3076            checkTime(startTime, "startProcess: done updating pids map");
3077        } catch (RuntimeException e) {
3078            // XXX do better error recovery.
3079            app.setPid(0);
3080            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3081            if (app.isolated) {
3082                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3083            }
3084            Slog.e(TAG, "Failure starting process " + app.processName, e);
3085        }
3086    }
3087
3088    void updateUsageStats(ActivityRecord component, boolean resumed) {
3089        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3090        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3091        if (resumed) {
3092            if (mUsageStatsService != null) {
3093                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3094                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3095            }
3096            synchronized (stats) {
3097                stats.noteActivityResumedLocked(component.app.uid);
3098            }
3099        } else {
3100            if (mUsageStatsService != null) {
3101                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3102                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3103            }
3104            synchronized (stats) {
3105                stats.noteActivityPausedLocked(component.app.uid);
3106            }
3107        }
3108    }
3109
3110    Intent getHomeIntent() {
3111        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3112        intent.setComponent(mTopComponent);
3113        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3114            intent.addCategory(Intent.CATEGORY_HOME);
3115        }
3116        return intent;
3117    }
3118
3119    boolean startHomeActivityLocked(int userId) {
3120        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3121                && mTopAction == null) {
3122            // We are running in factory test mode, but unable to find
3123            // the factory test app, so just sit around displaying the
3124            // error message and don't try to start anything.
3125            return false;
3126        }
3127        Intent intent = getHomeIntent();
3128        ActivityInfo aInfo =
3129            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3130        if (aInfo != null) {
3131            intent.setComponent(new ComponentName(
3132                    aInfo.applicationInfo.packageName, aInfo.name));
3133            // Don't do this if the home app is currently being
3134            // instrumented.
3135            aInfo = new ActivityInfo(aInfo);
3136            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3137            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3138                    aInfo.applicationInfo.uid, true);
3139            if (app == null || app.instrumentationClass == null) {
3140                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3141                mStackSupervisor.startHomeActivity(intent, aInfo);
3142            }
3143        }
3144
3145        return true;
3146    }
3147
3148    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3149        ActivityInfo ai = null;
3150        ComponentName comp = intent.getComponent();
3151        try {
3152            if (comp != null) {
3153                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3154            } else {
3155                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3156                        intent,
3157                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3158                            flags, userId);
3159
3160                if (info != null) {
3161                    ai = info.activityInfo;
3162                }
3163            }
3164        } catch (RemoteException e) {
3165            // ignore
3166        }
3167
3168        return ai;
3169    }
3170
3171    /**
3172     * Starts the "new version setup screen" if appropriate.
3173     */
3174    void startSetupActivityLocked() {
3175        // Only do this once per boot.
3176        if (mCheckedForSetup) {
3177            return;
3178        }
3179
3180        // We will show this screen if the current one is a different
3181        // version than the last one shown, and we are not running in
3182        // low-level factory test mode.
3183        final ContentResolver resolver = mContext.getContentResolver();
3184        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3185                Settings.Global.getInt(resolver,
3186                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3187            mCheckedForSetup = true;
3188
3189            // See if we should be showing the platform update setup UI.
3190            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3191            List<ResolveInfo> ris = mContext.getPackageManager()
3192                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3193
3194            // We don't allow third party apps to replace this.
3195            ResolveInfo ri = null;
3196            for (int i=0; ris != null && i<ris.size(); i++) {
3197                if ((ris.get(i).activityInfo.applicationInfo.flags
3198                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3199                    ri = ris.get(i);
3200                    break;
3201                }
3202            }
3203
3204            if (ri != null) {
3205                String vers = ri.activityInfo.metaData != null
3206                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3207                        : null;
3208                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3209                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3210                            Intent.METADATA_SETUP_VERSION);
3211                }
3212                String lastVers = Settings.Secure.getString(
3213                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3214                if (vers != null && !vers.equals(lastVers)) {
3215                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3216                    intent.setComponent(new ComponentName(
3217                            ri.activityInfo.packageName, ri.activityInfo.name));
3218                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3219                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3220                            null);
3221                }
3222            }
3223        }
3224    }
3225
3226    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3227        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3228    }
3229
3230    void enforceNotIsolatedCaller(String caller) {
3231        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3232            throw new SecurityException("Isolated process not allowed to call " + caller);
3233        }
3234    }
3235
3236    void enforceShellRestriction(String restriction, int userHandle) {
3237        if (Binder.getCallingUid() == Process.SHELL_UID) {
3238            if (userHandle < 0
3239                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3240                throw new SecurityException("Shell does not have permission to access user "
3241                        + userHandle);
3242            }
3243        }
3244    }
3245
3246    @Override
3247    public int getFrontActivityScreenCompatMode() {
3248        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3249        synchronized (this) {
3250            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3251        }
3252    }
3253
3254    @Override
3255    public void setFrontActivityScreenCompatMode(int mode) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setFrontActivityScreenCompatMode");
3258        synchronized (this) {
3259            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3260        }
3261    }
3262
3263    @Override
3264    public int getPackageScreenCompatMode(String packageName) {
3265        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3266        synchronized (this) {
3267            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3268        }
3269    }
3270
3271    @Override
3272    public void setPackageScreenCompatMode(String packageName, int mode) {
3273        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3274                "setPackageScreenCompatMode");
3275        synchronized (this) {
3276            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3277        }
3278    }
3279
3280    @Override
3281    public boolean getPackageAskScreenCompat(String packageName) {
3282        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3283        synchronized (this) {
3284            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3285        }
3286    }
3287
3288    @Override
3289    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3290        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3291                "setPackageAskScreenCompat");
3292        synchronized (this) {
3293            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3294        }
3295    }
3296
3297    private void dispatchProcessesChanged() {
3298        int N;
3299        synchronized (this) {
3300            N = mPendingProcessChanges.size();
3301            if (mActiveProcessChanges.length < N) {
3302                mActiveProcessChanges = new ProcessChangeItem[N];
3303            }
3304            mPendingProcessChanges.toArray(mActiveProcessChanges);
3305            mAvailProcessChanges.addAll(mPendingProcessChanges);
3306            mPendingProcessChanges.clear();
3307            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3308        }
3309
3310        int i = mProcessObservers.beginBroadcast();
3311        while (i > 0) {
3312            i--;
3313            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3314            if (observer != null) {
3315                try {
3316                    for (int j=0; j<N; j++) {
3317                        ProcessChangeItem item = mActiveProcessChanges[j];
3318                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3319                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3320                                    + item.pid + " uid=" + item.uid + ": "
3321                                    + item.foregroundActivities);
3322                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3323                                    item.foregroundActivities);
3324                        }
3325                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3326                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3327                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3328                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3329                        }
3330                    }
3331                } catch (RemoteException e) {
3332                }
3333            }
3334        }
3335        mProcessObservers.finishBroadcast();
3336    }
3337
3338    private void dispatchProcessDied(int pid, int uid) {
3339        int i = mProcessObservers.beginBroadcast();
3340        while (i > 0) {
3341            i--;
3342            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3343            if (observer != null) {
3344                try {
3345                    observer.onProcessDied(pid, uid);
3346                } catch (RemoteException e) {
3347                }
3348            }
3349        }
3350        mProcessObservers.finishBroadcast();
3351    }
3352
3353    @Override
3354    public final int startActivity(IApplicationThread caller, String callingPackage,
3355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3356            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3357        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3358            resultWho, requestCode, startFlags, profilerInfo, options,
3359            UserHandle.getCallingUserId());
3360    }
3361
3362    @Override
3363    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3364            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3365            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3366        enforceNotIsolatedCaller("startActivity");
3367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3368                false, ALLOW_FULL_ONLY, "startActivity", null);
3369        // TODO: Switch to user app stacks here.
3370        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3371                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3372                profilerInfo, null, null, options, userId, null, null);
3373    }
3374
3375    @Override
3376    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3377            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3378            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3379
3380        // This is very dangerous -- it allows you to perform a start activity (including
3381        // permission grants) as any app that may launch one of your own activities.  So
3382        // we will only allow this to be done from activities that are part of the core framework,
3383        // and then only when they are running as the system.
3384        final ActivityRecord sourceRecord;
3385        final int targetUid;
3386        final String targetPackage;
3387        synchronized (this) {
3388            if (resultTo == null) {
3389                throw new SecurityException("Must be called from an activity");
3390            }
3391            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3392            if (sourceRecord == null) {
3393                throw new SecurityException("Called with bad activity token: " + resultTo);
3394            }
3395            if (!sourceRecord.info.packageName.equals("android")) {
3396                throw new SecurityException(
3397                        "Must be called from an activity that is declared in the android package");
3398            }
3399            if (sourceRecord.app == null) {
3400                throw new SecurityException("Called without a process attached to activity");
3401            }
3402            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3403                // This is still okay, as long as this activity is running under the
3404                // uid of the original calling activity.
3405                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3406                    throw new SecurityException(
3407                            "Calling activity in uid " + sourceRecord.app.uid
3408                                    + " must be system uid or original calling uid "
3409                                    + sourceRecord.launchedFromUid);
3410                }
3411            }
3412            targetUid = sourceRecord.launchedFromUid;
3413            targetPackage = sourceRecord.launchedFromPackage;
3414        }
3415
3416        if (userId == UserHandle.USER_NULL) {
3417            userId = UserHandle.getUserId(sourceRecord.app.uid);
3418        }
3419
3420        // TODO: Switch to user app stacks here.
3421        try {
3422            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3423                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3424                    null, null, options, userId, null, null);
3425            return ret;
3426        } catch (SecurityException e) {
3427            // XXX need to figure out how to propagate to original app.
3428            // A SecurityException here is generally actually a fault of the original
3429            // calling activity (such as a fairly granting permissions), so propagate it
3430            // back to them.
3431            /*
3432            StringBuilder msg = new StringBuilder();
3433            msg.append("While launching");
3434            msg.append(intent.toString());
3435            msg.append(": ");
3436            msg.append(e.getMessage());
3437            */
3438            throw e;
3439        }
3440    }
3441
3442    @Override
3443    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3444            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3445            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3446        enforceNotIsolatedCaller("startActivityAndWait");
3447        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3448                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3449        WaitResult res = new WaitResult();
3450        // TODO: Switch to user app stacks here.
3451        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3452                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3453                options, userId, null, null);
3454        return res;
3455    }
3456
3457    @Override
3458    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3459            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3460            int startFlags, Configuration config, Bundle options, int userId) {
3461        enforceNotIsolatedCaller("startActivityWithConfig");
3462        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3463                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3464        // TODO: Switch to user app stacks here.
3465        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3466                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3467                null, null, config, options, userId, null, null);
3468        return ret;
3469    }
3470
3471    @Override
3472    public int startActivityIntentSender(IApplicationThread caller,
3473            IntentSender intent, Intent fillInIntent, String resolvedType,
3474            IBinder resultTo, String resultWho, int requestCode,
3475            int flagsMask, int flagsValues, Bundle options) {
3476        enforceNotIsolatedCaller("startActivityIntentSender");
3477        // Refuse possible leaked file descriptors
3478        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3479            throw new IllegalArgumentException("File descriptors passed in Intent");
3480        }
3481
3482        IIntentSender sender = intent.getTarget();
3483        if (!(sender instanceof PendingIntentRecord)) {
3484            throw new IllegalArgumentException("Bad PendingIntent object");
3485        }
3486
3487        PendingIntentRecord pir = (PendingIntentRecord)sender;
3488
3489        synchronized (this) {
3490            // If this is coming from the currently resumed activity, it is
3491            // effectively saying that app switches are allowed at this point.
3492            final ActivityStack stack = getFocusedStack();
3493            if (stack.mResumedActivity != null &&
3494                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3495                mAppSwitchesAllowedTime = 0;
3496            }
3497        }
3498        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3499                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3500        return ret;
3501    }
3502
3503    @Override
3504    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3505            Intent intent, String resolvedType, IVoiceInteractionSession session,
3506            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3507            Bundle options, int userId) {
3508        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3509                != PackageManager.PERMISSION_GRANTED) {
3510            String msg = "Permission Denial: startVoiceActivity() from pid="
3511                    + Binder.getCallingPid()
3512                    + ", uid=" + Binder.getCallingUid()
3513                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3514            Slog.w(TAG, msg);
3515            throw new SecurityException(msg);
3516        }
3517        if (session == null || interactor == null) {
3518            throw new NullPointerException("null session or interactor");
3519        }
3520        userId = handleIncomingUser(callingPid, callingUid, userId,
3521                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3522        // TODO: Switch to user app stacks here.
3523        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3524                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3525                null, options, userId, null, null);
3526    }
3527
3528    @Override
3529    public boolean startNextMatchingActivity(IBinder callingActivity,
3530            Intent intent, Bundle options) {
3531        // Refuse possible leaked file descriptors
3532        if (intent != null && intent.hasFileDescriptors() == true) {
3533            throw new IllegalArgumentException("File descriptors passed in Intent");
3534        }
3535
3536        synchronized (this) {
3537            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3538            if (r == null) {
3539                ActivityOptions.abort(options);
3540                return false;
3541            }
3542            if (r.app == null || r.app.thread == null) {
3543                // The caller is not running...  d'oh!
3544                ActivityOptions.abort(options);
3545                return false;
3546            }
3547            intent = new Intent(intent);
3548            // The caller is not allowed to change the data.
3549            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3550            // And we are resetting to find the next component...
3551            intent.setComponent(null);
3552
3553            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3554
3555            ActivityInfo aInfo = null;
3556            try {
3557                List<ResolveInfo> resolves =
3558                    AppGlobals.getPackageManager().queryIntentActivities(
3559                            intent, r.resolvedType,
3560                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3561                            UserHandle.getCallingUserId());
3562
3563                // Look for the original activity in the list...
3564                final int N = resolves != null ? resolves.size() : 0;
3565                for (int i=0; i<N; i++) {
3566                    ResolveInfo rInfo = resolves.get(i);
3567                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3568                            && rInfo.activityInfo.name.equals(r.info.name)) {
3569                        // We found the current one...  the next matching is
3570                        // after it.
3571                        i++;
3572                        if (i<N) {
3573                            aInfo = resolves.get(i).activityInfo;
3574                        }
3575                        if (debug) {
3576                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3577                                    + "/" + r.info.name);
3578                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3579                                    + "/" + aInfo.name);
3580                        }
3581                        break;
3582                    }
3583                }
3584            } catch (RemoteException e) {
3585            }
3586
3587            if (aInfo == null) {
3588                // Nobody who is next!
3589                ActivityOptions.abort(options);
3590                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3591                return false;
3592            }
3593
3594            intent.setComponent(new ComponentName(
3595                    aInfo.applicationInfo.packageName, aInfo.name));
3596            intent.setFlags(intent.getFlags()&~(
3597                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3598                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3599                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3600                    Intent.FLAG_ACTIVITY_NEW_TASK));
3601
3602            // Okay now we need to start the new activity, replacing the
3603            // currently running activity.  This is a little tricky because
3604            // we want to start the new one as if the current one is finished,
3605            // but not finish the current one first so that there is no flicker.
3606            // And thus...
3607            final boolean wasFinishing = r.finishing;
3608            r.finishing = true;
3609
3610            // Propagate reply information over to the new activity.
3611            final ActivityRecord resultTo = r.resultTo;
3612            final String resultWho = r.resultWho;
3613            final int requestCode = r.requestCode;
3614            r.resultTo = null;
3615            if (resultTo != null) {
3616                resultTo.removeResultsLocked(r, resultWho, requestCode);
3617            }
3618
3619            final long origId = Binder.clearCallingIdentity();
3620            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3621                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3622                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3623                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3624            Binder.restoreCallingIdentity(origId);
3625
3626            r.finishing = wasFinishing;
3627            if (res != ActivityManager.START_SUCCESS) {
3628                return false;
3629            }
3630            return true;
3631        }
3632    }
3633
3634    @Override
3635    public final int startActivityFromRecents(int taskId, Bundle options) {
3636        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3637            String msg = "Permission Denial: startActivityFromRecents called without " +
3638                    START_TASKS_FROM_RECENTS;
3639            Slog.w(TAG, msg);
3640            throw new SecurityException(msg);
3641        }
3642        return startActivityFromRecentsInner(taskId, options);
3643    }
3644
3645    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3646        final TaskRecord task;
3647        final int callingUid;
3648        final String callingPackage;
3649        final Intent intent;
3650        final int userId;
3651        synchronized (this) {
3652            task = recentTaskForIdLocked(taskId);
3653            if (task == null) {
3654                throw new IllegalArgumentException("Task " + taskId + " not found.");
3655            }
3656            callingUid = task.mCallingUid;
3657            callingPackage = task.mCallingPackage;
3658            intent = task.intent;
3659            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3660            userId = task.userId;
3661        }
3662        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3663                options, userId, null, task);
3664    }
3665
3666    final int startActivityInPackage(int uid, String callingPackage,
3667            Intent intent, String resolvedType, IBinder resultTo,
3668            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3669            IActivityContainer container, TaskRecord inTask) {
3670
3671        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3672                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3673
3674        // TODO: Switch to user app stacks here.
3675        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3676                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3677                null, null, null, options, userId, container, inTask);
3678        return ret;
3679    }
3680
3681    @Override
3682    public final int startActivities(IApplicationThread caller, String callingPackage,
3683            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3684            int userId) {
3685        enforceNotIsolatedCaller("startActivities");
3686        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3687                false, ALLOW_FULL_ONLY, "startActivity", null);
3688        // TODO: Switch to user app stacks here.
3689        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3690                resolvedTypes, resultTo, options, userId);
3691        return ret;
3692    }
3693
3694    final int startActivitiesInPackage(int uid, String callingPackage,
3695            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3696            Bundle options, int userId) {
3697
3698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3699                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3700        // TODO: Switch to user app stacks here.
3701        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3702                resultTo, options, userId);
3703        return ret;
3704    }
3705
3706    //explicitly remove thd old information in mRecentTasks when removing existing user.
3707    private void removeRecentTasksForUserLocked(int userId) {
3708        if(userId <= 0) {
3709            Slog.i(TAG, "Can't remove recent task on user " + userId);
3710            return;
3711        }
3712
3713        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3714            TaskRecord tr = mRecentTasks.get(i);
3715            if (tr.userId == userId) {
3716                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3717                        + " when finishing user" + userId);
3718                mRecentTasks.remove(i);
3719                tr.removedFromRecents();
3720            }
3721        }
3722
3723        // Remove tasks from persistent storage.
3724        notifyTaskPersisterLocked(null, true);
3725    }
3726
3727    // Sort by taskId
3728    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3729        @Override
3730        public int compare(TaskRecord lhs, TaskRecord rhs) {
3731            return rhs.taskId - lhs.taskId;
3732        }
3733    };
3734
3735    // Extract the affiliates of the chain containing mRecentTasks[start].
3736    private int processNextAffiliateChainLocked(int start) {
3737        final TaskRecord startTask = mRecentTasks.get(start);
3738        final int affiliateId = startTask.mAffiliatedTaskId;
3739
3740        // Quick identification of isolated tasks. I.e. those not launched behind.
3741        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3742                startTask.mNextAffiliate == null) {
3743            // There is still a slim chance that there are other tasks that point to this task
3744            // and that the chain is so messed up that this task no longer points to them but
3745            // the gain of this optimization outweighs the risk.
3746            startTask.inRecents = true;
3747            return start + 1;
3748        }
3749
3750        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3751        mTmpRecents.clear();
3752        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3753            final TaskRecord task = mRecentTasks.get(i);
3754            if (task.mAffiliatedTaskId == affiliateId) {
3755                mRecentTasks.remove(i);
3756                mTmpRecents.add(task);
3757            }
3758        }
3759
3760        // Sort them all by taskId. That is the order they were create in and that order will
3761        // always be correct.
3762        Collections.sort(mTmpRecents, mTaskRecordComparator);
3763
3764        // Go through and fix up the linked list.
3765        // The first one is the end of the chain and has no next.
3766        final TaskRecord first = mTmpRecents.get(0);
3767        first.inRecents = true;
3768        if (first.mNextAffiliate != null) {
3769            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3770            first.setNextAffiliate(null);
3771            notifyTaskPersisterLocked(first, false);
3772        }
3773        // Everything in the middle is doubly linked from next to prev.
3774        final int tmpSize = mTmpRecents.size();
3775        for (int i = 0; i < tmpSize - 1; ++i) {
3776            final TaskRecord next = mTmpRecents.get(i);
3777            final TaskRecord prev = mTmpRecents.get(i + 1);
3778            if (next.mPrevAffiliate != prev) {
3779                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3780                        " setting prev=" + prev);
3781                next.setPrevAffiliate(prev);
3782                notifyTaskPersisterLocked(next, false);
3783            }
3784            if (prev.mNextAffiliate != next) {
3785                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3786                        " setting next=" + next);
3787                prev.setNextAffiliate(next);
3788                notifyTaskPersisterLocked(prev, false);
3789            }
3790            prev.inRecents = true;
3791        }
3792        // The last one is the beginning of the list and has no prev.
3793        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3794        if (last.mPrevAffiliate != null) {
3795            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3796            last.setPrevAffiliate(null);
3797            notifyTaskPersisterLocked(last, false);
3798        }
3799
3800        // Insert the group back into mRecentTasks at start.
3801        mRecentTasks.addAll(start, mTmpRecents);
3802
3803        // Let the caller know where we left off.
3804        return start + tmpSize;
3805    }
3806
3807    /**
3808     * Update the recent tasks lists: make sure tasks should still be here (their
3809     * applications / activities still exist), update their availability, fixup ordering
3810     * of affiliations.
3811     */
3812    void cleanupRecentTasksLocked(int userId) {
3813        if (mRecentTasks == null) {
3814            // Happens when called from the packagemanager broadcast before boot.
3815            return;
3816        }
3817
3818        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3819        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3820        final IPackageManager pm = AppGlobals.getPackageManager();
3821        final ActivityInfo dummyAct = new ActivityInfo();
3822        final ApplicationInfo dummyApp = new ApplicationInfo();
3823
3824        int N = mRecentTasks.size();
3825
3826        int[] users = userId == UserHandle.USER_ALL
3827                ? getUsersLocked() : new int[] { userId };
3828        for (int user : users) {
3829            for (int i = 0; i < N; i++) {
3830                TaskRecord task = mRecentTasks.get(i);
3831                if (task.userId != user) {
3832                    // Only look at tasks for the user ID of interest.
3833                    continue;
3834                }
3835                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3836                    // This situation is broken, and we should just get rid of it now.
3837                    mRecentTasks.remove(i);
3838                    task.removedFromRecents();
3839                    i--;
3840                    N--;
3841                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3842                    continue;
3843                }
3844                // Check whether this activity is currently available.
3845                if (task.realActivity != null) {
3846                    ActivityInfo ai = availActCache.get(task.realActivity);
3847                    if (ai == null) {
3848                        try {
3849                            ai = pm.getActivityInfo(task.realActivity,
3850                                    PackageManager.GET_UNINSTALLED_PACKAGES
3851                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3852                        } catch (RemoteException e) {
3853                            // Will never happen.
3854                            continue;
3855                        }
3856                        if (ai == null) {
3857                            ai = dummyAct;
3858                        }
3859                        availActCache.put(task.realActivity, ai);
3860                    }
3861                    if (ai == dummyAct) {
3862                        // This could be either because the activity no longer exists, or the
3863                        // app is temporarily gone.  For the former we want to remove the recents
3864                        // entry; for the latter we want to mark it as unavailable.
3865                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3866                        if (app == null) {
3867                            try {
3868                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3869                                        PackageManager.GET_UNINSTALLED_PACKAGES
3870                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3871                            } catch (RemoteException e) {
3872                                // Will never happen.
3873                                continue;
3874                            }
3875                            if (app == null) {
3876                                app = dummyApp;
3877                            }
3878                            availAppCache.put(task.realActivity.getPackageName(), app);
3879                        }
3880                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3881                            // Doesn't exist any more!  Good-bye.
3882                            mRecentTasks.remove(i);
3883                            task.removedFromRecents();
3884                            i--;
3885                            N--;
3886                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3887                            continue;
3888                        } else {
3889                            // Otherwise just not available for now.
3890                            if (task.isAvailable) {
3891                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3892                                        + task);
3893                            }
3894                            task.isAvailable = false;
3895                        }
3896                    } else {
3897                        if (!ai.enabled || !ai.applicationInfo.enabled
3898                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3899                            if (task.isAvailable) {
3900                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3901                                        + task + " (enabled=" + ai.enabled + "/"
3902                                        + ai.applicationInfo.enabled +  " flags="
3903                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3904                            }
3905                            task.isAvailable = false;
3906                        } else {
3907                            if (!task.isAvailable) {
3908                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3909                                        + task);
3910                            }
3911                            task.isAvailable = true;
3912                        }
3913                    }
3914                }
3915            }
3916        }
3917
3918        // Verify the affiliate chain for each task.
3919        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3920        }
3921
3922        mTmpRecents.clear();
3923        // mRecentTasks is now in sorted, affiliated order.
3924    }
3925
3926    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3927        int N = mRecentTasks.size();
3928        TaskRecord top = task;
3929        int topIndex = taskIndex;
3930        while (top.mNextAffiliate != null && topIndex > 0) {
3931            top = top.mNextAffiliate;
3932            topIndex--;
3933        }
3934        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3935                + topIndex + " from intial " + taskIndex);
3936        // Find the end of the chain, doing a sanity check along the way.
3937        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3938        int endIndex = topIndex;
3939        TaskRecord prev = top;
3940        while (endIndex < N) {
3941            TaskRecord cur = mRecentTasks.get(endIndex);
3942            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3943                    + endIndex + " " + cur);
3944            if (cur == top) {
3945                // Verify start of the chain.
3946                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3947                    Slog.wtf(TAG, "Bad chain @" + endIndex
3948                            + ": first task has next affiliate: " + prev);
3949                    sane = false;
3950                    break;
3951                }
3952            } else {
3953                // Verify middle of the chain's next points back to the one before.
3954                if (cur.mNextAffiliate != prev
3955                        || cur.mNextAffiliateTaskId != prev.taskId) {
3956                    Slog.wtf(TAG, "Bad chain @" + endIndex
3957                            + ": middle task " + cur + " @" + endIndex
3958                            + " has bad next affiliate "
3959                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3960                            + ", expected " + prev);
3961                    sane = false;
3962                    break;
3963                }
3964            }
3965            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3966                // Chain ends here.
3967                if (cur.mPrevAffiliate != null) {
3968                    Slog.wtf(TAG, "Bad chain @" + endIndex
3969                            + ": last task " + cur + " has previous affiliate "
3970                            + cur.mPrevAffiliate);
3971                    sane = false;
3972                }
3973                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3974                break;
3975            } else {
3976                // Verify middle of the chain's prev points to a valid item.
3977                if (cur.mPrevAffiliate == null) {
3978                    Slog.wtf(TAG, "Bad chain @" + endIndex
3979                            + ": task " + cur + " has previous affiliate "
3980                            + cur.mPrevAffiliate + " but should be id "
3981                            + cur.mPrevAffiliate);
3982                    sane = false;
3983                    break;
3984                }
3985            }
3986            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3987                Slog.wtf(TAG, "Bad chain @" + endIndex
3988                        + ": task " + cur + " has affiliated id "
3989                        + cur.mAffiliatedTaskId + " but should be "
3990                        + task.mAffiliatedTaskId);
3991                sane = false;
3992                break;
3993            }
3994            prev = cur;
3995            endIndex++;
3996            if (endIndex >= N) {
3997                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3998                        + ": last task " + prev);
3999                sane = false;
4000                break;
4001            }
4002        }
4003        if (sane) {
4004            if (endIndex < taskIndex) {
4005                Slog.wtf(TAG, "Bad chain @" + endIndex
4006                        + ": did not extend to task " + task + " @" + taskIndex);
4007                sane = false;
4008            }
4009        }
4010        if (sane) {
4011            // All looks good, we can just move all of the affiliated tasks
4012            // to the top.
4013            for (int i=topIndex; i<=endIndex; i++) {
4014                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4015                        + " from " + i + " to " + (i-topIndex));
4016                TaskRecord cur = mRecentTasks.remove(i);
4017                mRecentTasks.add(i-topIndex, cur);
4018            }
4019            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4020                    + " to " + endIndex);
4021            return true;
4022        }
4023
4024        // Whoops, couldn't do it.
4025        return false;
4026    }
4027
4028    final void addRecentTaskLocked(TaskRecord task) {
4029        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4030                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4031                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4032
4033        int N = mRecentTasks.size();
4034        // Quick case: check if the top-most recent task is the same.
4035        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4036            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4037            return;
4038        }
4039        // Another quick case: check if this is part of a set of affiliated
4040        // tasks that are at the top.
4041        if (isAffiliated && N > 0 && task.inRecents
4042                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4043            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4044                    + " at top when adding " + task);
4045            return;
4046        }
4047        // Another quick case: never add voice sessions.
4048        if (task.voiceSession != null) {
4049            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4050            return;
4051        }
4052
4053        boolean needAffiliationFix = false;
4054
4055        // Slightly less quick case: the task is already in recents, so all we need
4056        // to do is move it.
4057        if (task.inRecents) {
4058            int taskIndex = mRecentTasks.indexOf(task);
4059            if (taskIndex >= 0) {
4060                if (!isAffiliated) {
4061                    // Simple case: this is not an affiliated task, so we just move it to the front.
4062                    mRecentTasks.remove(taskIndex);
4063                    mRecentTasks.add(0, task);
4064                    notifyTaskPersisterLocked(task, false);
4065                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4066                            + " from " + taskIndex);
4067                    return;
4068                } else {
4069                    // More complicated: need to keep all affiliated tasks together.
4070                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4071                        // All went well.
4072                        return;
4073                    }
4074
4075                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4076                    // everything and then go through our general path of adding a new task.
4077                    needAffiliationFix = true;
4078                }
4079            } else {
4080                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4081                needAffiliationFix = true;
4082            }
4083        }
4084
4085        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4086        trimRecentsForTaskLocked(task, true);
4087
4088        N = mRecentTasks.size();
4089        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4090            final TaskRecord tr = mRecentTasks.remove(N - 1);
4091            tr.removedFromRecents();
4092            N--;
4093        }
4094        task.inRecents = true;
4095        if (!isAffiliated || needAffiliationFix) {
4096            // If this is a simple non-affiliated task, or we had some failure trying to
4097            // handle it as part of an affilated task, then just place it at the top.
4098            mRecentTasks.add(0, task);
4099        } else if (isAffiliated) {
4100            // If this is a new affiliated task, then move all of the affiliated tasks
4101            // to the front and insert this new one.
4102            TaskRecord other = task.mNextAffiliate;
4103            if (other == null) {
4104                other = task.mPrevAffiliate;
4105            }
4106            if (other != null) {
4107                int otherIndex = mRecentTasks.indexOf(other);
4108                if (otherIndex >= 0) {
4109                    // Insert new task at appropriate location.
4110                    int taskIndex;
4111                    if (other == task.mNextAffiliate) {
4112                        // We found the index of our next affiliation, which is who is
4113                        // before us in the list, so add after that point.
4114                        taskIndex = otherIndex+1;
4115                    } else {
4116                        // We found the index of our previous affiliation, which is who is
4117                        // after us in the list, so add at their position.
4118                        taskIndex = otherIndex;
4119                    }
4120                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4121                            + taskIndex + ": " + task);
4122                    mRecentTasks.add(taskIndex, task);
4123
4124                    // Now move everything to the front.
4125                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4126                        // All went well.
4127                        return;
4128                    }
4129
4130                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4131                    // everything and then go through our general path of adding a new task.
4132                    needAffiliationFix = true;
4133                } else {
4134                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4135                            + other);
4136                    needAffiliationFix = true;
4137                }
4138            } else {
4139                if (DEBUG_RECENTS) Slog.d(TAG,
4140                        "addRecent: adding affiliated task without next/prev:" + task);
4141                needAffiliationFix = true;
4142            }
4143        }
4144        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4145
4146        if (needAffiliationFix) {
4147            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4148            cleanupRecentTasksLocked(task.userId);
4149        }
4150    }
4151
4152    /**
4153     * If needed, remove oldest existing entries in recents that are for the same kind
4154     * of task as the given one.
4155     */
4156    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4157        int N = mRecentTasks.size();
4158        final Intent intent = task.intent;
4159        final boolean document = intent != null && intent.isDocument();
4160
4161        int maxRecents = task.maxRecents - 1;
4162        for (int i=0; i<N; i++) {
4163            final TaskRecord tr = mRecentTasks.get(i);
4164            if (task != tr) {
4165                if (task.userId != tr.userId) {
4166                    continue;
4167                }
4168                if (i > MAX_RECENT_BITMAPS) {
4169                    tr.freeLastThumbnail();
4170                }
4171                final Intent trIntent = tr.intent;
4172                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4173                    (intent == null || !intent.filterEquals(trIntent))) {
4174                    continue;
4175                }
4176                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4177                if (document && trIsDocument) {
4178                    // These are the same document activity (not necessarily the same doc).
4179                    if (maxRecents > 0) {
4180                        --maxRecents;
4181                        continue;
4182                    }
4183                    // Hit the maximum number of documents for this task. Fall through
4184                    // and remove this document from recents.
4185                } else if (document || trIsDocument) {
4186                    // Only one of these is a document. Not the droid we're looking for.
4187                    continue;
4188                }
4189            }
4190
4191            if (!doTrim) {
4192                // If the caller is not actually asking for a trim, just tell them we reached
4193                // a point where the trim would happen.
4194                return i;
4195            }
4196
4197            // Either task and tr are the same or, their affinities match or their intents match
4198            // and neither of them is a document, or they are documents using the same activity
4199            // and their maxRecents has been reached.
4200            tr.disposeThumbnail();
4201            mRecentTasks.remove(i);
4202            if (task != tr) {
4203                tr.removedFromRecents();
4204            }
4205            i--;
4206            N--;
4207            if (task.intent == null) {
4208                // If the new recent task we are adding is not fully
4209                // specified, then replace it with the existing recent task.
4210                task = tr;
4211            }
4212            notifyTaskPersisterLocked(tr, false);
4213        }
4214
4215        return -1;
4216    }
4217
4218    @Override
4219    public void reportActivityFullyDrawn(IBinder token) {
4220        synchronized (this) {
4221            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4222            if (r == null) {
4223                return;
4224            }
4225            r.reportFullyDrawnLocked();
4226        }
4227    }
4228
4229    @Override
4230    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4231        synchronized (this) {
4232            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4233            if (r == null) {
4234                return;
4235            }
4236            final long origId = Binder.clearCallingIdentity();
4237            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4238            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4239                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4240            if (config != null) {
4241                r.frozenBeforeDestroy = true;
4242                if (!updateConfigurationLocked(config, r, false, false)) {
4243                    mStackSupervisor.resumeTopActivitiesLocked();
4244                }
4245            }
4246            Binder.restoreCallingIdentity(origId);
4247        }
4248    }
4249
4250    @Override
4251    public int getRequestedOrientation(IBinder token) {
4252        synchronized (this) {
4253            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4254            if (r == null) {
4255                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4256            }
4257            return mWindowManager.getAppOrientation(r.appToken);
4258        }
4259    }
4260
4261    /**
4262     * This is the internal entry point for handling Activity.finish().
4263     *
4264     * @param token The Binder token referencing the Activity we want to finish.
4265     * @param resultCode Result code, if any, from this Activity.
4266     * @param resultData Result data (Intent), if any, from this Activity.
4267     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4268     *            the root Activity in the task.
4269     *
4270     * @return Returns true if the activity successfully finished, or false if it is still running.
4271     */
4272    @Override
4273    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4274            boolean finishTask) {
4275        // Refuse possible leaked file descriptors
4276        if (resultData != null && resultData.hasFileDescriptors() == true) {
4277            throw new IllegalArgumentException("File descriptors passed in Intent");
4278        }
4279
4280        synchronized(this) {
4281            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4282            if (r == null) {
4283                return true;
4284            }
4285            // Keep track of the root activity of the task before we finish it
4286            TaskRecord tr = r.task;
4287            ActivityRecord rootR = tr.getRootActivity();
4288            if (rootR == null) {
4289                Slog.w(TAG, "Finishing task with all activities already finished");
4290            }
4291            // Do not allow task to finish in Lock Task mode.
4292            if (tr == mStackSupervisor.mLockTaskModeTask) {
4293                if (rootR == r) {
4294                    Slog.i(TAG, "Not finishing task in lock task mode");
4295                    mStackSupervisor.showLockTaskToast();
4296                    return false;
4297                }
4298            }
4299            if (mController != null) {
4300                // Find the first activity that is not finishing.
4301                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4302                if (next != null) {
4303                    // ask watcher if this is allowed
4304                    boolean resumeOK = true;
4305                    try {
4306                        resumeOK = mController.activityResuming(next.packageName);
4307                    } catch (RemoteException e) {
4308                        mController = null;
4309                        Watchdog.getInstance().setActivityController(null);
4310                    }
4311
4312                    if (!resumeOK) {
4313                        Slog.i(TAG, "Not finishing activity because controller resumed");
4314                        return false;
4315                    }
4316                }
4317            }
4318            final long origId = Binder.clearCallingIdentity();
4319            try {
4320                boolean res;
4321                if (finishTask && r == rootR) {
4322                    // If requested, remove the task that is associated to this activity only if it
4323                    // was the root activity in the task. The result code and data is ignored
4324                    // because we don't support returning them across task boundaries.
4325                    res = removeTaskByIdLocked(tr.taskId, false);
4326                    if (!res) {
4327                        Slog.i(TAG, "Removing task failed to finish activity");
4328                    }
4329                } else {
4330                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4331                            resultData, "app-request", true);
4332                    if (!res) {
4333                        Slog.i(TAG, "Failed to finish by app-request");
4334                    }
4335                }
4336                return res;
4337            } finally {
4338                Binder.restoreCallingIdentity(origId);
4339            }
4340        }
4341    }
4342
4343    @Override
4344    public final void finishHeavyWeightApp() {
4345        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4346                != PackageManager.PERMISSION_GRANTED) {
4347            String msg = "Permission Denial: finishHeavyWeightApp() 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            if (mHeavyWeightProcess == null) {
4357                return;
4358            }
4359
4360            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4361                    mHeavyWeightProcess.activities);
4362            for (int i=0; i<activities.size(); i++) {
4363                ActivityRecord r = activities.get(i);
4364                if (!r.finishing) {
4365                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4366                            null, "finish-heavy", true);
4367                }
4368            }
4369
4370            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4371                    mHeavyWeightProcess.userId, 0));
4372            mHeavyWeightProcess = null;
4373        }
4374    }
4375
4376    @Override
4377    public void crashApplication(int uid, int initialPid, String packageName,
4378            String message) {
4379        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4380                != PackageManager.PERMISSION_GRANTED) {
4381            String msg = "Permission Denial: crashApplication() from pid="
4382                    + Binder.getCallingPid()
4383                    + ", uid=" + Binder.getCallingUid()
4384                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4385            Slog.w(TAG, msg);
4386            throw new SecurityException(msg);
4387        }
4388
4389        synchronized(this) {
4390            ProcessRecord proc = null;
4391
4392            // Figure out which process to kill.  We don't trust that initialPid
4393            // still has any relation to current pids, so must scan through the
4394            // list.
4395            synchronized (mPidsSelfLocked) {
4396                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4397                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4398                    if (p.uid != uid) {
4399                        continue;
4400                    }
4401                    if (p.pid == initialPid) {
4402                        proc = p;
4403                        break;
4404                    }
4405                    if (p.pkgList.containsKey(packageName)) {
4406                        proc = p;
4407                    }
4408                }
4409            }
4410
4411            if (proc == null) {
4412                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4413                        + " initialPid=" + initialPid
4414                        + " packageName=" + packageName);
4415                return;
4416            }
4417
4418            if (proc.thread != null) {
4419                if (proc.pid == Process.myPid()) {
4420                    Log.w(TAG, "crashApplication: trying to crash self!");
4421                    return;
4422                }
4423                long ident = Binder.clearCallingIdentity();
4424                try {
4425                    proc.thread.scheduleCrash(message);
4426                } catch (RemoteException e) {
4427                }
4428                Binder.restoreCallingIdentity(ident);
4429            }
4430        }
4431    }
4432
4433    @Override
4434    public final void finishSubActivity(IBinder token, String resultWho,
4435            int requestCode) {
4436        synchronized(this) {
4437            final long origId = Binder.clearCallingIdentity();
4438            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4439            if (r != null) {
4440                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4441            }
4442            Binder.restoreCallingIdentity(origId);
4443        }
4444    }
4445
4446    @Override
4447    public boolean finishActivityAffinity(IBinder token) {
4448        synchronized(this) {
4449            final long origId = Binder.clearCallingIdentity();
4450            try {
4451                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4452
4453                ActivityRecord rootR = r.task.getRootActivity();
4454                // Do not allow task to finish in Lock Task mode.
4455                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4456                    if (rootR == r) {
4457                        mStackSupervisor.showLockTaskToast();
4458                        return false;
4459                    }
4460                }
4461                boolean res = false;
4462                if (r != null) {
4463                    res = r.task.stack.finishActivityAffinityLocked(r);
4464                }
4465                return res;
4466            } finally {
4467                Binder.restoreCallingIdentity(origId);
4468            }
4469        }
4470    }
4471
4472    @Override
4473    public void finishVoiceTask(IVoiceInteractionSession session) {
4474        synchronized(this) {
4475            final long origId = Binder.clearCallingIdentity();
4476            try {
4477                mStackSupervisor.finishVoiceTask(session);
4478            } finally {
4479                Binder.restoreCallingIdentity(origId);
4480            }
4481        }
4482
4483    }
4484
4485    @Override
4486    public boolean releaseActivityInstance(IBinder token) {
4487        synchronized(this) {
4488            final long origId = Binder.clearCallingIdentity();
4489            try {
4490                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4491                if (r.task == null || r.task.stack == null) {
4492                    return false;
4493                }
4494                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4495            } finally {
4496                Binder.restoreCallingIdentity(origId);
4497            }
4498        }
4499    }
4500
4501    @Override
4502    public void releaseSomeActivities(IApplicationThread appInt) {
4503        synchronized(this) {
4504            final long origId = Binder.clearCallingIdentity();
4505            try {
4506                ProcessRecord app = getRecordForAppLocked(appInt);
4507                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4508            } finally {
4509                Binder.restoreCallingIdentity(origId);
4510            }
4511        }
4512    }
4513
4514    @Override
4515    public boolean willActivityBeVisible(IBinder token) {
4516        synchronized(this) {
4517            ActivityStack stack = ActivityRecord.getStackLocked(token);
4518            if (stack != null) {
4519                return stack.willActivityBeVisibleLocked(token);
4520            }
4521            return false;
4522        }
4523    }
4524
4525    @Override
4526    public void overridePendingTransition(IBinder token, String packageName,
4527            int enterAnim, int exitAnim) {
4528        synchronized(this) {
4529            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4530            if (self == null) {
4531                return;
4532            }
4533
4534            final long origId = Binder.clearCallingIdentity();
4535
4536            if (self.state == ActivityState.RESUMED
4537                    || self.state == ActivityState.PAUSING) {
4538                mWindowManager.overridePendingAppTransition(packageName,
4539                        enterAnim, exitAnim, null);
4540            }
4541
4542            Binder.restoreCallingIdentity(origId);
4543        }
4544    }
4545
4546    /**
4547     * Main function for removing an existing process from the activity manager
4548     * as a result of that process going away.  Clears out all connections
4549     * to the process.
4550     */
4551    private final void handleAppDiedLocked(ProcessRecord app,
4552            boolean restarting, boolean allowRestart) {
4553        int pid = app.pid;
4554        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4555        if (!kept && !restarting) {
4556            removeLruProcessLocked(app);
4557            if (pid > 0) {
4558                ProcessList.remove(pid);
4559            }
4560        }
4561
4562        if (mProfileProc == app) {
4563            clearProfilerLocked();
4564        }
4565
4566        // Remove this application's activities from active lists.
4567        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4568
4569        app.activities.clear();
4570
4571        if (app.instrumentationClass != null) {
4572            Slog.w(TAG, "Crash of app " + app.processName
4573                  + " running instrumentation " + app.instrumentationClass);
4574            Bundle info = new Bundle();
4575            info.putString("shortMsg", "Process crashed.");
4576            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4577        }
4578
4579        if (!restarting) {
4580            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4581                // If there was nothing to resume, and we are not already
4582                // restarting this process, but there is a visible activity that
4583                // is hosted by the process...  then make sure all visible
4584                // activities are running, taking care of restarting this
4585                // process.
4586                if (hasVisibleActivities) {
4587                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4588                }
4589            }
4590        }
4591    }
4592
4593    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4594        IBinder threadBinder = thread.asBinder();
4595        // Find the application record.
4596        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4597            ProcessRecord rec = mLruProcesses.get(i);
4598            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4599                return i;
4600            }
4601        }
4602        return -1;
4603    }
4604
4605    final ProcessRecord getRecordForAppLocked(
4606            IApplicationThread thread) {
4607        if (thread == null) {
4608            return null;
4609        }
4610
4611        int appIndex = getLRURecordIndexForAppLocked(thread);
4612        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4613    }
4614
4615    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4616        // If there are no longer any background processes running,
4617        // and the app that died was not running instrumentation,
4618        // then tell everyone we are now low on memory.
4619        boolean haveBg = false;
4620        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4621            ProcessRecord rec = mLruProcesses.get(i);
4622            if (rec.thread != null
4623                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4624                haveBg = true;
4625                break;
4626            }
4627        }
4628
4629        if (!haveBg) {
4630            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4631            if (doReport) {
4632                long now = SystemClock.uptimeMillis();
4633                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4634                    doReport = false;
4635                } else {
4636                    mLastMemUsageReportTime = now;
4637                }
4638            }
4639            final ArrayList<ProcessMemInfo> memInfos
4640                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4641            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4642            long now = SystemClock.uptimeMillis();
4643            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4644                ProcessRecord rec = mLruProcesses.get(i);
4645                if (rec == dyingProc || rec.thread == null) {
4646                    continue;
4647                }
4648                if (doReport) {
4649                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4650                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4651                }
4652                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4653                    // The low memory report is overriding any current
4654                    // state for a GC request.  Make sure to do
4655                    // heavy/important/visible/foreground processes first.
4656                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4657                        rec.lastRequestedGc = 0;
4658                    } else {
4659                        rec.lastRequestedGc = rec.lastLowMemory;
4660                    }
4661                    rec.reportLowMemory = true;
4662                    rec.lastLowMemory = now;
4663                    mProcessesToGc.remove(rec);
4664                    addProcessToGcListLocked(rec);
4665                }
4666            }
4667            if (doReport) {
4668                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4669                mHandler.sendMessage(msg);
4670            }
4671            scheduleAppGcsLocked();
4672        }
4673    }
4674
4675    final void appDiedLocked(ProcessRecord app) {
4676       appDiedLocked(app, app.pid, app.thread);
4677    }
4678
4679    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4680        // First check if this ProcessRecord is actually active for the pid.
4681        synchronized (mPidsSelfLocked) {
4682            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4683            if (curProc != app) {
4684                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4685                return;
4686            }
4687        }
4688
4689        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4690        synchronized (stats) {
4691            stats.noteProcessDiedLocked(app.info.uid, pid);
4692        }
4693
4694        if (!app.killed) {
4695            Process.killProcessQuiet(pid);
4696            Process.killProcessGroup(app.info.uid, pid);
4697            app.killed = true;
4698        }
4699
4700        // Clean up already done if the process has been re-started.
4701        if (app.pid == pid && app.thread != null &&
4702                app.thread.asBinder() == thread.asBinder()) {
4703            boolean doLowMem = app.instrumentationClass == null;
4704            boolean doOomAdj = doLowMem;
4705            if (!app.killedByAm) {
4706                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4707                        + ") has died");
4708                mAllowLowerMemLevel = true;
4709            } else {
4710                // Note that we always want to do oom adj to update our state with the
4711                // new number of procs.
4712                mAllowLowerMemLevel = false;
4713                doLowMem = false;
4714            }
4715            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4716            if (DEBUG_CLEANUP) Slog.v(
4717                TAG, "Dying app: " + app + ", pid: " + pid
4718                + ", thread: " + thread.asBinder());
4719            handleAppDiedLocked(app, false, true);
4720
4721            if (doOomAdj) {
4722                updateOomAdjLocked();
4723            }
4724            if (doLowMem) {
4725                doLowMemReportIfNeededLocked(app);
4726            }
4727        } else if (app.pid != pid) {
4728            // A new process has already been started.
4729            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4730                    + ") has died and restarted (pid " + app.pid + ").");
4731            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4732        } else if (DEBUG_PROCESSES) {
4733            Slog.d(TAG, "Received spurious death notification for thread "
4734                    + thread.asBinder());
4735        }
4736    }
4737
4738    /**
4739     * If a stack trace dump file is configured, dump process stack traces.
4740     * @param clearTraces causes the dump file to be erased prior to the new
4741     *    traces being written, if true; when false, the new traces will be
4742     *    appended to any existing file content.
4743     * @param firstPids of dalvik VM processes to dump stack traces for first
4744     * @param lastPids of dalvik VM processes to dump stack traces for last
4745     * @param nativeProcs optional list of native process names to dump stack crawls
4746     * @return file containing stack traces, or null if no dump file is configured
4747     */
4748    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4749            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4750        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4751        if (tracesPath == null || tracesPath.length() == 0) {
4752            return null;
4753        }
4754
4755        File tracesFile = new File(tracesPath);
4756        try {
4757            File tracesDir = tracesFile.getParentFile();
4758            if (!tracesDir.exists()) {
4759                tracesDir.mkdirs();
4760                if (!SELinux.restorecon(tracesDir)) {
4761                    return null;
4762                }
4763            }
4764            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4765
4766            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4767            tracesFile.createNewFile();
4768            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4769        } catch (IOException e) {
4770            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4771            return null;
4772        }
4773
4774        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4775        return tracesFile;
4776    }
4777
4778    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4779            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4780        // Use a FileObserver to detect when traces finish writing.
4781        // The order of traces is considered important to maintain for legibility.
4782        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4783            @Override
4784            public synchronized void onEvent(int event, String path) { notify(); }
4785        };
4786
4787        try {
4788            observer.startWatching();
4789
4790            // First collect all of the stacks of the most important pids.
4791            if (firstPids != null) {
4792                try {
4793                    int num = firstPids.size();
4794                    for (int i = 0; i < num; i++) {
4795                        synchronized (observer) {
4796                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4797                            observer.wait(200);  // Wait for write-close, give up after 200msec
4798                        }
4799                    }
4800                } catch (InterruptedException e) {
4801                    Slog.wtf(TAG, e);
4802                }
4803            }
4804
4805            // Next collect the stacks of the native pids
4806            if (nativeProcs != null) {
4807                int[] pids = Process.getPidsForCommands(nativeProcs);
4808                if (pids != null) {
4809                    for (int pid : pids) {
4810                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4811                    }
4812                }
4813            }
4814
4815            // Lastly, measure CPU usage.
4816            if (processCpuTracker != null) {
4817                processCpuTracker.init();
4818                System.gc();
4819                processCpuTracker.update();
4820                try {
4821                    synchronized (processCpuTracker) {
4822                        processCpuTracker.wait(500); // measure over 1/2 second.
4823                    }
4824                } catch (InterruptedException e) {
4825                }
4826                processCpuTracker.update();
4827
4828                // We'll take the stack crawls of just the top apps using CPU.
4829                final int N = processCpuTracker.countWorkingStats();
4830                int numProcs = 0;
4831                for (int i=0; i<N && numProcs<5; i++) {
4832                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4833                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4834                        numProcs++;
4835                        try {
4836                            synchronized (observer) {
4837                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4838                                observer.wait(200);  // Wait for write-close, give up after 200msec
4839                            }
4840                        } catch (InterruptedException e) {
4841                            Slog.wtf(TAG, e);
4842                        }
4843
4844                    }
4845                }
4846            }
4847        } finally {
4848            observer.stopWatching();
4849        }
4850    }
4851
4852    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4853        if (true || IS_USER_BUILD) {
4854            return;
4855        }
4856        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4857        if (tracesPath == null || tracesPath.length() == 0) {
4858            return;
4859        }
4860
4861        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4862        StrictMode.allowThreadDiskWrites();
4863        try {
4864            final File tracesFile = new File(tracesPath);
4865            final File tracesDir = tracesFile.getParentFile();
4866            final File tracesTmp = new File(tracesDir, "__tmp__");
4867            try {
4868                if (!tracesDir.exists()) {
4869                    tracesDir.mkdirs();
4870                    if (!SELinux.restorecon(tracesDir.getPath())) {
4871                        return;
4872                    }
4873                }
4874                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4875
4876                if (tracesFile.exists()) {
4877                    tracesTmp.delete();
4878                    tracesFile.renameTo(tracesTmp);
4879                }
4880                StringBuilder sb = new StringBuilder();
4881                Time tobj = new Time();
4882                tobj.set(System.currentTimeMillis());
4883                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4884                sb.append(": ");
4885                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4886                sb.append(" since ");
4887                sb.append(msg);
4888                FileOutputStream fos = new FileOutputStream(tracesFile);
4889                fos.write(sb.toString().getBytes());
4890                if (app == null) {
4891                    fos.write("\n*** No application process!".getBytes());
4892                }
4893                fos.close();
4894                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4895            } catch (IOException e) {
4896                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4897                return;
4898            }
4899
4900            if (app != null) {
4901                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4902                firstPids.add(app.pid);
4903                dumpStackTraces(tracesPath, firstPids, null, null, null);
4904            }
4905
4906            File lastTracesFile = null;
4907            File curTracesFile = null;
4908            for (int i=9; i>=0; i--) {
4909                String name = String.format(Locale.US, "slow%02d.txt", i);
4910                curTracesFile = new File(tracesDir, name);
4911                if (curTracesFile.exists()) {
4912                    if (lastTracesFile != null) {
4913                        curTracesFile.renameTo(lastTracesFile);
4914                    } else {
4915                        curTracesFile.delete();
4916                    }
4917                }
4918                lastTracesFile = curTracesFile;
4919            }
4920            tracesFile.renameTo(curTracesFile);
4921            if (tracesTmp.exists()) {
4922                tracesTmp.renameTo(tracesFile);
4923            }
4924        } finally {
4925            StrictMode.setThreadPolicy(oldPolicy);
4926        }
4927    }
4928
4929    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4930            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4931        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4932        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4933
4934        if (mController != null) {
4935            try {
4936                // 0 == continue, -1 = kill process immediately
4937                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4938                if (res < 0 && app.pid != MY_PID) {
4939                    app.kill("anr", true);
4940                }
4941            } catch (RemoteException e) {
4942                mController = null;
4943                Watchdog.getInstance().setActivityController(null);
4944            }
4945        }
4946
4947        long anrTime = SystemClock.uptimeMillis();
4948        if (MONITOR_CPU_USAGE) {
4949            updateCpuStatsNow();
4950        }
4951
4952        synchronized (this) {
4953            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4954            if (mShuttingDown) {
4955                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4956                return;
4957            } else if (app.notResponding) {
4958                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4959                return;
4960            } else if (app.crashing) {
4961                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4962                return;
4963            }
4964
4965            // In case we come through here for the same app before completing
4966            // this one, mark as anring now so we will bail out.
4967            app.notResponding = true;
4968
4969            // Log the ANR to the event log.
4970            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4971                    app.processName, app.info.flags, annotation);
4972
4973            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4974            firstPids.add(app.pid);
4975
4976            int parentPid = app.pid;
4977            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4978            if (parentPid != app.pid) firstPids.add(parentPid);
4979
4980            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4981
4982            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4983                ProcessRecord r = mLruProcesses.get(i);
4984                if (r != null && r.thread != null) {
4985                    int pid = r.pid;
4986                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4987                        if (r.persistent) {
4988                            firstPids.add(pid);
4989                        } else {
4990                            lastPids.put(pid, Boolean.TRUE);
4991                        }
4992                    }
4993                }
4994            }
4995        }
4996
4997        // Log the ANR to the main log.
4998        StringBuilder info = new StringBuilder();
4999        info.setLength(0);
5000        info.append("ANR in ").append(app.processName);
5001        if (activity != null && activity.shortComponentName != null) {
5002            info.append(" (").append(activity.shortComponentName).append(")");
5003        }
5004        info.append("\n");
5005        info.append("PID: ").append(app.pid).append("\n");
5006        if (annotation != null) {
5007            info.append("Reason: ").append(annotation).append("\n");
5008        }
5009        if (parent != null && parent != activity) {
5010            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5011        }
5012
5013        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5014
5015        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5016                NATIVE_STACKS_OF_INTEREST);
5017
5018        String cpuInfo = null;
5019        if (MONITOR_CPU_USAGE) {
5020            updateCpuStatsNow();
5021            synchronized (mProcessCpuTracker) {
5022                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5023            }
5024            info.append(processCpuTracker.printCurrentLoad());
5025            info.append(cpuInfo);
5026        }
5027
5028        info.append(processCpuTracker.printCurrentState(anrTime));
5029
5030        Slog.e(TAG, info.toString());
5031        if (tracesFile == null) {
5032            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5033            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5034        }
5035
5036        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5037                cpuInfo, tracesFile, null);
5038
5039        if (mController != null) {
5040            try {
5041                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5042                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5043                if (res != 0) {
5044                    if (res < 0 && app.pid != MY_PID) {
5045                        app.kill("anr", true);
5046                    } else {
5047                        synchronized (this) {
5048                            mServices.scheduleServiceTimeoutLocked(app);
5049                        }
5050                    }
5051                    return;
5052                }
5053            } catch (RemoteException e) {
5054                mController = null;
5055                Watchdog.getInstance().setActivityController(null);
5056            }
5057        }
5058
5059        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5060        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5061                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5062
5063        synchronized (this) {
5064            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5065
5066            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5067                app.kill("bg anr", true);
5068                return;
5069            }
5070
5071            // Set the app's notResponding state, and look up the errorReportReceiver
5072            makeAppNotRespondingLocked(app,
5073                    activity != null ? activity.shortComponentName : null,
5074                    annotation != null ? "ANR " + annotation : "ANR",
5075                    info.toString());
5076
5077            // Bring up the infamous App Not Responding dialog
5078            Message msg = Message.obtain();
5079            HashMap<String, Object> map = new HashMap<String, Object>();
5080            msg.what = SHOW_NOT_RESPONDING_MSG;
5081            msg.obj = map;
5082            msg.arg1 = aboveSystem ? 1 : 0;
5083            map.put("app", app);
5084            if (activity != null) {
5085                map.put("activity", activity);
5086            }
5087
5088            mHandler.sendMessage(msg);
5089        }
5090    }
5091
5092    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5093        if (!mLaunchWarningShown) {
5094            mLaunchWarningShown = true;
5095            mHandler.post(new Runnable() {
5096                @Override
5097                public void run() {
5098                    synchronized (ActivityManagerService.this) {
5099                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5100                        d.show();
5101                        mHandler.postDelayed(new Runnable() {
5102                            @Override
5103                            public void run() {
5104                                synchronized (ActivityManagerService.this) {
5105                                    d.dismiss();
5106                                    mLaunchWarningShown = false;
5107                                }
5108                            }
5109                        }, 4000);
5110                    }
5111                }
5112            });
5113        }
5114    }
5115
5116    @Override
5117    public boolean clearApplicationUserData(final String packageName,
5118            final IPackageDataObserver observer, int userId) {
5119        enforceNotIsolatedCaller("clearApplicationUserData");
5120        int uid = Binder.getCallingUid();
5121        int pid = Binder.getCallingPid();
5122        userId = handleIncomingUser(pid, uid,
5123                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5124        long callingId = Binder.clearCallingIdentity();
5125        try {
5126            IPackageManager pm = AppGlobals.getPackageManager();
5127            int pkgUid = -1;
5128            synchronized(this) {
5129                try {
5130                    pkgUid = pm.getPackageUid(packageName, userId);
5131                } catch (RemoteException e) {
5132                }
5133                if (pkgUid == -1) {
5134                    Slog.w(TAG, "Invalid packageName: " + packageName);
5135                    if (observer != null) {
5136                        try {
5137                            observer.onRemoveCompleted(packageName, false);
5138                        } catch (RemoteException e) {
5139                            Slog.i(TAG, "Observer no longer exists.");
5140                        }
5141                    }
5142                    return false;
5143                }
5144                if (uid == pkgUid || checkComponentPermission(
5145                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5146                        pid, uid, -1, true)
5147                        == PackageManager.PERMISSION_GRANTED) {
5148                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5149                } else {
5150                    throw new SecurityException("PID " + pid + " does not have permission "
5151                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5152                                    + " of package " + packageName);
5153                }
5154
5155                // Remove all tasks match the cleared application package and user
5156                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5157                    final TaskRecord tr = mRecentTasks.get(i);
5158                    final String taskPackageName =
5159                            tr.getBaseIntent().getComponent().getPackageName();
5160                    if (tr.userId != userId) continue;
5161                    if (!taskPackageName.equals(packageName)) continue;
5162                    removeTaskByIdLocked(tr.taskId, false);
5163                }
5164            }
5165
5166            try {
5167                // Clear application user data
5168                pm.clearApplicationUserData(packageName, observer, userId);
5169
5170                synchronized(this) {
5171                    // Remove all permissions granted from/to this package
5172                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5173                }
5174
5175                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5176                        Uri.fromParts("package", packageName, null));
5177                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5178                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5179                        null, null, 0, null, null, null, false, false, userId);
5180            } catch (RemoteException e) {
5181            }
5182        } finally {
5183            Binder.restoreCallingIdentity(callingId);
5184        }
5185        return true;
5186    }
5187
5188    @Override
5189    public void killBackgroundProcesses(final String packageName, int userId) {
5190        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5191                != PackageManager.PERMISSION_GRANTED &&
5192                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5193                        != PackageManager.PERMISSION_GRANTED) {
5194            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5195                    + Binder.getCallingPid()
5196                    + ", uid=" + Binder.getCallingUid()
5197                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5198            Slog.w(TAG, msg);
5199            throw new SecurityException(msg);
5200        }
5201
5202        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5203                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5204        long callingId = Binder.clearCallingIdentity();
5205        try {
5206            IPackageManager pm = AppGlobals.getPackageManager();
5207            synchronized(this) {
5208                int appId = -1;
5209                try {
5210                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5211                } catch (RemoteException e) {
5212                }
5213                if (appId == -1) {
5214                    Slog.w(TAG, "Invalid packageName: " + packageName);
5215                    return;
5216                }
5217                killPackageProcessesLocked(packageName, appId, userId,
5218                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5219            }
5220        } finally {
5221            Binder.restoreCallingIdentity(callingId);
5222        }
5223    }
5224
5225    @Override
5226    public void killAllBackgroundProcesses() {
5227        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5228                != PackageManager.PERMISSION_GRANTED) {
5229            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5230                    + Binder.getCallingPid()
5231                    + ", uid=" + Binder.getCallingUid()
5232                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5233            Slog.w(TAG, msg);
5234            throw new SecurityException(msg);
5235        }
5236
5237        long callingId = Binder.clearCallingIdentity();
5238        try {
5239            synchronized(this) {
5240                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5241                final int NP = mProcessNames.getMap().size();
5242                for (int ip=0; ip<NP; ip++) {
5243                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5244                    final int NA = apps.size();
5245                    for (int ia=0; ia<NA; ia++) {
5246                        ProcessRecord app = apps.valueAt(ia);
5247                        if (app.persistent) {
5248                            // we don't kill persistent processes
5249                            continue;
5250                        }
5251                        if (app.removed) {
5252                            procs.add(app);
5253                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5254                            app.removed = true;
5255                            procs.add(app);
5256                        }
5257                    }
5258                }
5259
5260                int N = procs.size();
5261                for (int i=0; i<N; i++) {
5262                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5263                }
5264                mAllowLowerMemLevel = true;
5265                updateOomAdjLocked();
5266                doLowMemReportIfNeededLocked(null);
5267            }
5268        } finally {
5269            Binder.restoreCallingIdentity(callingId);
5270        }
5271    }
5272
5273    @Override
5274    public void forceStopPackage(final String packageName, int userId) {
5275        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5276                != PackageManager.PERMISSION_GRANTED) {
5277            String msg = "Permission Denial: forceStopPackage() from pid="
5278                    + Binder.getCallingPid()
5279                    + ", uid=" + Binder.getCallingUid()
5280                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5281            Slog.w(TAG, msg);
5282            throw new SecurityException(msg);
5283        }
5284        final int callingPid = Binder.getCallingPid();
5285        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5286                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5287        long callingId = Binder.clearCallingIdentity();
5288        try {
5289            IPackageManager pm = AppGlobals.getPackageManager();
5290            synchronized(this) {
5291                int[] users = userId == UserHandle.USER_ALL
5292                        ? getUsersLocked() : new int[] { userId };
5293                for (int user : users) {
5294                    int pkgUid = -1;
5295                    try {
5296                        pkgUid = pm.getPackageUid(packageName, user);
5297                    } catch (RemoteException e) {
5298                    }
5299                    if (pkgUid == -1) {
5300                        Slog.w(TAG, "Invalid packageName: " + packageName);
5301                        continue;
5302                    }
5303                    try {
5304                        pm.setPackageStoppedState(packageName, true, user);
5305                    } catch (RemoteException e) {
5306                    } catch (IllegalArgumentException e) {
5307                        Slog.w(TAG, "Failed trying to unstop package "
5308                                + packageName + ": " + e);
5309                    }
5310                    if (isUserRunningLocked(user, false)) {
5311                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5312                    }
5313                }
5314            }
5315        } finally {
5316            Binder.restoreCallingIdentity(callingId);
5317        }
5318    }
5319
5320    @Override
5321    public void addPackageDependency(String packageName) {
5322        synchronized (this) {
5323            int callingPid = Binder.getCallingPid();
5324            if (callingPid == Process.myPid()) {
5325                //  Yeah, um, no.
5326                Slog.w(TAG, "Can't addPackageDependency on system process");
5327                return;
5328            }
5329            ProcessRecord proc;
5330            synchronized (mPidsSelfLocked) {
5331                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5332            }
5333            if (proc != null) {
5334                if (proc.pkgDeps == null) {
5335                    proc.pkgDeps = new ArraySet<String>(1);
5336                }
5337                proc.pkgDeps.add(packageName);
5338            }
5339        }
5340    }
5341
5342    /*
5343     * The pkg name and app id have to be specified.
5344     */
5345    @Override
5346    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5347        if (pkg == null) {
5348            return;
5349        }
5350        // Make sure the uid is valid.
5351        if (appid < 0) {
5352            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5353            return;
5354        }
5355        int callerUid = Binder.getCallingUid();
5356        // Only the system server can kill an application
5357        if (callerUid == Process.SYSTEM_UID) {
5358            // Post an aysnc message to kill the application
5359            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5360            msg.arg1 = appid;
5361            msg.arg2 = 0;
5362            Bundle bundle = new Bundle();
5363            bundle.putString("pkg", pkg);
5364            bundle.putString("reason", reason);
5365            msg.obj = bundle;
5366            mHandler.sendMessage(msg);
5367        } else {
5368            throw new SecurityException(callerUid + " cannot kill pkg: " +
5369                    pkg);
5370        }
5371    }
5372
5373    @Override
5374    public void closeSystemDialogs(String reason) {
5375        enforceNotIsolatedCaller("closeSystemDialogs");
5376
5377        final int pid = Binder.getCallingPid();
5378        final int uid = Binder.getCallingUid();
5379        final long origId = Binder.clearCallingIdentity();
5380        try {
5381            synchronized (this) {
5382                // Only allow this from foreground processes, so that background
5383                // applications can't abuse it to prevent system UI from being shown.
5384                if (uid >= Process.FIRST_APPLICATION_UID) {
5385                    ProcessRecord proc;
5386                    synchronized (mPidsSelfLocked) {
5387                        proc = mPidsSelfLocked.get(pid);
5388                    }
5389                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5390                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5391                                + " from background process " + proc);
5392                        return;
5393                    }
5394                }
5395                closeSystemDialogsLocked(reason);
5396            }
5397        } finally {
5398            Binder.restoreCallingIdentity(origId);
5399        }
5400    }
5401
5402    void closeSystemDialogsLocked(String reason) {
5403        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5404        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5405                | Intent.FLAG_RECEIVER_FOREGROUND);
5406        if (reason != null) {
5407            intent.putExtra("reason", reason);
5408        }
5409        mWindowManager.closeSystemDialogs(reason);
5410
5411        mStackSupervisor.closeSystemDialogsLocked();
5412
5413        broadcastIntentLocked(null, null, intent, null,
5414                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5415                Process.SYSTEM_UID, UserHandle.USER_ALL);
5416    }
5417
5418    @Override
5419    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5420        enforceNotIsolatedCaller("getProcessMemoryInfo");
5421        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5422        for (int i=pids.length-1; i>=0; i--) {
5423            ProcessRecord proc;
5424            int oomAdj;
5425            synchronized (this) {
5426                synchronized (mPidsSelfLocked) {
5427                    proc = mPidsSelfLocked.get(pids[i]);
5428                    oomAdj = proc != null ? proc.setAdj : 0;
5429                }
5430            }
5431            infos[i] = new Debug.MemoryInfo();
5432            Debug.getMemoryInfo(pids[i], infos[i]);
5433            if (proc != null) {
5434                synchronized (this) {
5435                    if (proc.thread != null && proc.setAdj == oomAdj) {
5436                        // Record this for posterity if the process has been stable.
5437                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5438                                infos[i].getTotalUss(), false, proc.pkgList);
5439                    }
5440                }
5441            }
5442        }
5443        return infos;
5444    }
5445
5446    @Override
5447    public long[] getProcessPss(int[] pids) {
5448        enforceNotIsolatedCaller("getProcessPss");
5449        long[] pss = new long[pids.length];
5450        for (int i=pids.length-1; i>=0; i--) {
5451            ProcessRecord proc;
5452            int oomAdj;
5453            synchronized (this) {
5454                synchronized (mPidsSelfLocked) {
5455                    proc = mPidsSelfLocked.get(pids[i]);
5456                    oomAdj = proc != null ? proc.setAdj : 0;
5457                }
5458            }
5459            long[] tmpUss = new long[1];
5460            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5461            if (proc != null) {
5462                synchronized (this) {
5463                    if (proc.thread != null && proc.setAdj == oomAdj) {
5464                        // Record this for posterity if the process has been stable.
5465                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5466                    }
5467                }
5468            }
5469        }
5470        return pss;
5471    }
5472
5473    @Override
5474    public void killApplicationProcess(String processName, int uid) {
5475        if (processName == null) {
5476            return;
5477        }
5478
5479        int callerUid = Binder.getCallingUid();
5480        // Only the system server can kill an application
5481        if (callerUid == Process.SYSTEM_UID) {
5482            synchronized (this) {
5483                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5484                if (app != null && app.thread != null) {
5485                    try {
5486                        app.thread.scheduleSuicide();
5487                    } catch (RemoteException e) {
5488                        // If the other end already died, then our work here is done.
5489                    }
5490                } else {
5491                    Slog.w(TAG, "Process/uid not found attempting kill of "
5492                            + processName + " / " + uid);
5493                }
5494            }
5495        } else {
5496            throw new SecurityException(callerUid + " cannot kill app process: " +
5497                    processName);
5498        }
5499    }
5500
5501    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5502        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5503                false, true, false, false, UserHandle.getUserId(uid), reason);
5504        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5505                Uri.fromParts("package", packageName, null));
5506        if (!mProcessesReady) {
5507            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5508                    | Intent.FLAG_RECEIVER_FOREGROUND);
5509        }
5510        intent.putExtra(Intent.EXTRA_UID, uid);
5511        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5512        broadcastIntentLocked(null, null, intent,
5513                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5514                false, false,
5515                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5516    }
5517
5518    private void forceStopUserLocked(int userId, String reason) {
5519        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5520        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5521        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5522                | Intent.FLAG_RECEIVER_FOREGROUND);
5523        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5524        broadcastIntentLocked(null, null, intent,
5525                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5526                false, false,
5527                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5528    }
5529
5530    private final boolean killPackageProcessesLocked(String packageName, int appId,
5531            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5532            boolean doit, boolean evenPersistent, String reason) {
5533        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5534
5535        // Remove all processes this package may have touched: all with the
5536        // same UID (except for the system or root user), and all whose name
5537        // matches the package name.
5538        final int NP = mProcessNames.getMap().size();
5539        for (int ip=0; ip<NP; ip++) {
5540            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5541            final int NA = apps.size();
5542            for (int ia=0; ia<NA; ia++) {
5543                ProcessRecord app = apps.valueAt(ia);
5544                if (app.persistent && !evenPersistent) {
5545                    // we don't kill persistent processes
5546                    continue;
5547                }
5548                if (app.removed) {
5549                    if (doit) {
5550                        procs.add(app);
5551                    }
5552                    continue;
5553                }
5554
5555                // Skip process if it doesn't meet our oom adj requirement.
5556                if (app.setAdj < minOomAdj) {
5557                    continue;
5558                }
5559
5560                // If no package is specified, we call all processes under the
5561                // give user id.
5562                if (packageName == null) {
5563                    if (app.userId != userId) {
5564                        continue;
5565                    }
5566                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5567                        continue;
5568                    }
5569                // Package has been specified, we want to hit all processes
5570                // that match it.  We need to qualify this by the processes
5571                // that are running under the specified app and user ID.
5572                } else {
5573                    final boolean isDep = app.pkgDeps != null
5574                            && app.pkgDeps.contains(packageName);
5575                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5576                        continue;
5577                    }
5578                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5579                        continue;
5580                    }
5581                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5582                        continue;
5583                    }
5584                }
5585
5586                // Process has passed all conditions, kill it!
5587                if (!doit) {
5588                    return true;
5589                }
5590                app.removed = true;
5591                procs.add(app);
5592            }
5593        }
5594
5595        int N = procs.size();
5596        for (int i=0; i<N; i++) {
5597            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5598        }
5599        updateOomAdjLocked();
5600        return N > 0;
5601    }
5602
5603    private final boolean forceStopPackageLocked(String name, int appId,
5604            boolean callerWillRestart, boolean purgeCache, boolean doit,
5605            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5606        int i;
5607        int N;
5608
5609        if (userId == UserHandle.USER_ALL && name == null) {
5610            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5611        }
5612
5613        if (appId < 0 && name != null) {
5614            try {
5615                appId = UserHandle.getAppId(
5616                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5617            } catch (RemoteException e) {
5618            }
5619        }
5620
5621        if (doit) {
5622            if (name != null) {
5623                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5624                        + " user=" + userId + ": " + reason);
5625            } else {
5626                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5627            }
5628
5629            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5630            for (int ip=pmap.size()-1; ip>=0; ip--) {
5631                SparseArray<Long> ba = pmap.valueAt(ip);
5632                for (i=ba.size()-1; i>=0; i--) {
5633                    boolean remove = false;
5634                    final int entUid = ba.keyAt(i);
5635                    if (name != null) {
5636                        if (userId == UserHandle.USER_ALL) {
5637                            if (UserHandle.getAppId(entUid) == appId) {
5638                                remove = true;
5639                            }
5640                        } else {
5641                            if (entUid == UserHandle.getUid(userId, appId)) {
5642                                remove = true;
5643                            }
5644                        }
5645                    } else if (UserHandle.getUserId(entUid) == userId) {
5646                        remove = true;
5647                    }
5648                    if (remove) {
5649                        ba.removeAt(i);
5650                    }
5651                }
5652                if (ba.size() == 0) {
5653                    pmap.removeAt(ip);
5654                }
5655            }
5656        }
5657
5658        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5659                -100, callerWillRestart, true, doit, evenPersistent,
5660                name == null ? ("stop user " + userId) : ("stop " + name));
5661
5662        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5663            if (!doit) {
5664                return true;
5665            }
5666            didSomething = true;
5667        }
5668
5669        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5670            if (!doit) {
5671                return true;
5672            }
5673            didSomething = true;
5674        }
5675
5676        if (name == null) {
5677            // Remove all sticky broadcasts from this user.
5678            mStickyBroadcasts.remove(userId);
5679        }
5680
5681        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5682        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5683                userId, providers)) {
5684            if (!doit) {
5685                return true;
5686            }
5687            didSomething = true;
5688        }
5689        N = providers.size();
5690        for (i=0; i<N; i++) {
5691            removeDyingProviderLocked(null, providers.get(i), true);
5692        }
5693
5694        // Remove transient permissions granted from/to this package/user
5695        removeUriPermissionsForPackageLocked(name, userId, false);
5696
5697        if (name == null || uninstalling) {
5698            // Remove pending intents.  For now we only do this when force
5699            // stopping users, because we have some problems when doing this
5700            // for packages -- app widgets are not currently cleaned up for
5701            // such packages, so they can be left with bad pending intents.
5702            if (mIntentSenderRecords.size() > 0) {
5703                Iterator<WeakReference<PendingIntentRecord>> it
5704                        = mIntentSenderRecords.values().iterator();
5705                while (it.hasNext()) {
5706                    WeakReference<PendingIntentRecord> wpir = it.next();
5707                    if (wpir == null) {
5708                        it.remove();
5709                        continue;
5710                    }
5711                    PendingIntentRecord pir = wpir.get();
5712                    if (pir == null) {
5713                        it.remove();
5714                        continue;
5715                    }
5716                    if (name == null) {
5717                        // Stopping user, remove all objects for the user.
5718                        if (pir.key.userId != userId) {
5719                            // Not the same user, skip it.
5720                            continue;
5721                        }
5722                    } else {
5723                        if (UserHandle.getAppId(pir.uid) != appId) {
5724                            // Different app id, skip it.
5725                            continue;
5726                        }
5727                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5728                            // Different user, skip it.
5729                            continue;
5730                        }
5731                        if (!pir.key.packageName.equals(name)) {
5732                            // Different package, skip it.
5733                            continue;
5734                        }
5735                    }
5736                    if (!doit) {
5737                        return true;
5738                    }
5739                    didSomething = true;
5740                    it.remove();
5741                    pir.canceled = true;
5742                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5743                        pir.key.activity.pendingResults.remove(pir.ref);
5744                    }
5745                }
5746            }
5747        }
5748
5749        if (doit) {
5750            if (purgeCache && name != null) {
5751                AttributeCache ac = AttributeCache.instance();
5752                if (ac != null) {
5753                    ac.removePackage(name);
5754                }
5755            }
5756            if (mBooted) {
5757                mStackSupervisor.resumeTopActivitiesLocked();
5758                mStackSupervisor.scheduleIdleLocked();
5759            }
5760        }
5761
5762        return didSomething;
5763    }
5764
5765    private final boolean removeProcessLocked(ProcessRecord app,
5766            boolean callerWillRestart, boolean allowRestart, String reason) {
5767        final String name = app.processName;
5768        final int uid = app.uid;
5769        if (DEBUG_PROCESSES) Slog.d(
5770            TAG, "Force removing proc " + app.toShortString() + " (" + name
5771            + "/" + uid + ")");
5772
5773        mProcessNames.remove(name, uid);
5774        mIsolatedProcesses.remove(app.uid);
5775        if (mHeavyWeightProcess == app) {
5776            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5777                    mHeavyWeightProcess.userId, 0));
5778            mHeavyWeightProcess = null;
5779        }
5780        boolean needRestart = false;
5781        if (app.pid > 0 && app.pid != MY_PID) {
5782            int pid = app.pid;
5783            synchronized (mPidsSelfLocked) {
5784                mPidsSelfLocked.remove(pid);
5785                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5786            }
5787            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5788            if (app.isolated) {
5789                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5790            }
5791            app.kill(reason, true);
5792            handleAppDiedLocked(app, true, allowRestart);
5793            removeLruProcessLocked(app);
5794
5795            if (app.persistent && !app.isolated) {
5796                if (!callerWillRestart) {
5797                    addAppLocked(app.info, false, null /* ABI override */);
5798                } else {
5799                    needRestart = true;
5800                }
5801            }
5802        } else {
5803            mRemovedProcesses.add(app);
5804        }
5805
5806        return needRestart;
5807    }
5808
5809    private final void processStartTimedOutLocked(ProcessRecord app) {
5810        final int pid = app.pid;
5811        boolean gone = false;
5812        synchronized (mPidsSelfLocked) {
5813            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5814            if (knownApp != null && knownApp.thread == null) {
5815                mPidsSelfLocked.remove(pid);
5816                gone = true;
5817            }
5818        }
5819
5820        if (gone) {
5821            Slog.w(TAG, "Process " + app + " failed to attach");
5822            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5823                    pid, app.uid, app.processName);
5824            mProcessNames.remove(app.processName, app.uid);
5825            mIsolatedProcesses.remove(app.uid);
5826            if (mHeavyWeightProcess == app) {
5827                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5828                        mHeavyWeightProcess.userId, 0));
5829                mHeavyWeightProcess = null;
5830            }
5831            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5832            if (app.isolated) {
5833                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5834            }
5835            // Take care of any launching providers waiting for this process.
5836            checkAppInLaunchingProvidersLocked(app, true);
5837            // Take care of any services that are waiting for the process.
5838            mServices.processStartTimedOutLocked(app);
5839            app.kill("start timeout", true);
5840            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5841                Slog.w(TAG, "Unattached app died before backup, skipping");
5842                try {
5843                    IBackupManager bm = IBackupManager.Stub.asInterface(
5844                            ServiceManager.getService(Context.BACKUP_SERVICE));
5845                    bm.agentDisconnected(app.info.packageName);
5846                } catch (RemoteException e) {
5847                    // Can't happen; the backup manager is local
5848                }
5849            }
5850            if (isPendingBroadcastProcessLocked(pid)) {
5851                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5852                skipPendingBroadcastLocked(pid);
5853            }
5854        } else {
5855            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5856        }
5857    }
5858
5859    private final boolean attachApplicationLocked(IApplicationThread thread,
5860            int pid) {
5861
5862        // Find the application record that is being attached...  either via
5863        // the pid if we are running in multiple processes, or just pull the
5864        // next app record if we are emulating process with anonymous threads.
5865        ProcessRecord app;
5866        if (pid != MY_PID && pid >= 0) {
5867            synchronized (mPidsSelfLocked) {
5868                app = mPidsSelfLocked.get(pid);
5869            }
5870        } else {
5871            app = null;
5872        }
5873
5874        if (app == null) {
5875            Slog.w(TAG, "No pending application record for pid " + pid
5876                    + " (IApplicationThread " + thread + "); dropping process");
5877            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5878            if (pid > 0 && pid != MY_PID) {
5879                Process.killProcessQuiet(pid);
5880                //TODO: Process.killProcessGroup(app.info.uid, pid);
5881            } else {
5882                try {
5883                    thread.scheduleExit();
5884                } catch (Exception e) {
5885                    // Ignore exceptions.
5886                }
5887            }
5888            return false;
5889        }
5890
5891        // If this application record is still attached to a previous
5892        // process, clean it up now.
5893        if (app.thread != null) {
5894            handleAppDiedLocked(app, true, true);
5895        }
5896
5897        // Tell the process all about itself.
5898
5899        if (localLOGV) Slog.v(
5900                TAG, "Binding process pid " + pid + " to record " + app);
5901
5902        final String processName = app.processName;
5903        try {
5904            AppDeathRecipient adr = new AppDeathRecipient(
5905                    app, pid, thread);
5906            thread.asBinder().linkToDeath(adr, 0);
5907            app.deathRecipient = adr;
5908        } catch (RemoteException e) {
5909            app.resetPackageList(mProcessStats);
5910            startProcessLocked(app, "link fail", processName);
5911            return false;
5912        }
5913
5914        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5915
5916        app.makeActive(thread, mProcessStats);
5917        app.curAdj = app.setAdj = -100;
5918        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5919        app.forcingToForeground = null;
5920        updateProcessForegroundLocked(app, false, false);
5921        app.hasShownUi = false;
5922        app.debugging = false;
5923        app.cached = false;
5924        app.killedByAm = false;
5925
5926        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5927
5928        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5929        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5930
5931        if (!normalMode) {
5932            Slog.i(TAG, "Launching preboot mode app: " + app);
5933        }
5934
5935        if (localLOGV) Slog.v(
5936            TAG, "New app record " + app
5937            + " thread=" + thread.asBinder() + " pid=" + pid);
5938        try {
5939            int testMode = IApplicationThread.DEBUG_OFF;
5940            if (mDebugApp != null && mDebugApp.equals(processName)) {
5941                testMode = mWaitForDebugger
5942                    ? IApplicationThread.DEBUG_WAIT
5943                    : IApplicationThread.DEBUG_ON;
5944                app.debugging = true;
5945                if (mDebugTransient) {
5946                    mDebugApp = mOrigDebugApp;
5947                    mWaitForDebugger = mOrigWaitForDebugger;
5948                }
5949            }
5950            String profileFile = app.instrumentationProfileFile;
5951            ParcelFileDescriptor profileFd = null;
5952            int samplingInterval = 0;
5953            boolean profileAutoStop = false;
5954            if (mProfileApp != null && mProfileApp.equals(processName)) {
5955                mProfileProc = app;
5956                profileFile = mProfileFile;
5957                profileFd = mProfileFd;
5958                samplingInterval = mSamplingInterval;
5959                profileAutoStop = mAutoStopProfiler;
5960            }
5961            boolean enableOpenGlTrace = false;
5962            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5963                enableOpenGlTrace = true;
5964                mOpenGlTraceApp = null;
5965            }
5966
5967            // If the app is being launched for restore or full backup, set it up specially
5968            boolean isRestrictedBackupMode = false;
5969            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5970                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5971                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5972                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5973            }
5974
5975            ensurePackageDexOpt(app.instrumentationInfo != null
5976                    ? app.instrumentationInfo.packageName
5977                    : app.info.packageName);
5978            if (app.instrumentationClass != null) {
5979                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5980            }
5981            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5982                    + processName + " with config " + mConfiguration);
5983            ApplicationInfo appInfo = app.instrumentationInfo != null
5984                    ? app.instrumentationInfo : app.info;
5985            app.compat = compatibilityInfoForPackageLocked(appInfo);
5986            if (profileFd != null) {
5987                profileFd = profileFd.dup();
5988            }
5989            ProfilerInfo profilerInfo = profileFile == null ? null
5990                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5991            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5992                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5993                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5994                    isRestrictedBackupMode || !normalMode, app.persistent,
5995                    new Configuration(mConfiguration), app.compat,
5996                    getCommonServicesLocked(app.isolated),
5997                    mCoreSettingsObserver.getCoreSettingsLocked());
5998            updateLruProcessLocked(app, false, null);
5999            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6000        } catch (Exception e) {
6001            // todo: Yikes!  What should we do?  For now we will try to
6002            // start another process, but that could easily get us in
6003            // an infinite loop of restarting processes...
6004            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6005
6006            app.resetPackageList(mProcessStats);
6007            app.unlinkDeathRecipient();
6008            startProcessLocked(app, "bind fail", processName);
6009            return false;
6010        }
6011
6012        // Remove this record from the list of starting applications.
6013        mPersistentStartingProcesses.remove(app);
6014        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6015                "Attach application locked removing on hold: " + app);
6016        mProcessesOnHold.remove(app);
6017
6018        boolean badApp = false;
6019        boolean didSomething = false;
6020
6021        // See if the top visible activity is waiting to run in this process...
6022        if (normalMode) {
6023            try {
6024                if (mStackSupervisor.attachApplicationLocked(app)) {
6025                    didSomething = true;
6026                }
6027            } catch (Exception e) {
6028                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6029                badApp = true;
6030            }
6031        }
6032
6033        // Find any services that should be running in this process...
6034        if (!badApp) {
6035            try {
6036                didSomething |= mServices.attachApplicationLocked(app, processName);
6037            } catch (Exception e) {
6038                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6039                badApp = true;
6040            }
6041        }
6042
6043        // Check if a next-broadcast receiver is in this process...
6044        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6045            try {
6046                didSomething |= sendPendingBroadcastsLocked(app);
6047            } catch (Exception e) {
6048                // If the app died trying to launch the receiver we declare it 'bad'
6049                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6050                badApp = true;
6051            }
6052        }
6053
6054        // Check whether the next backup agent is in this process...
6055        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6056            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6057            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6058            try {
6059                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6060                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6061                        mBackupTarget.backupMode);
6062            } catch (Exception e) {
6063                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6064                badApp = true;
6065            }
6066        }
6067
6068        if (badApp) {
6069            app.kill("error during init", true);
6070            handleAppDiedLocked(app, false, true);
6071            return false;
6072        }
6073
6074        if (!didSomething) {
6075            updateOomAdjLocked();
6076        }
6077
6078        return true;
6079    }
6080
6081    @Override
6082    public final void attachApplication(IApplicationThread thread) {
6083        synchronized (this) {
6084            int callingPid = Binder.getCallingPid();
6085            final long origId = Binder.clearCallingIdentity();
6086            attachApplicationLocked(thread, callingPid);
6087            Binder.restoreCallingIdentity(origId);
6088        }
6089    }
6090
6091    @Override
6092    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6093        final long origId = Binder.clearCallingIdentity();
6094        synchronized (this) {
6095            ActivityStack stack = ActivityRecord.getStackLocked(token);
6096            if (stack != null) {
6097                ActivityRecord r =
6098                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6099                if (stopProfiling) {
6100                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6101                        try {
6102                            mProfileFd.close();
6103                        } catch (IOException e) {
6104                        }
6105                        clearProfilerLocked();
6106                    }
6107                }
6108            }
6109        }
6110        Binder.restoreCallingIdentity(origId);
6111    }
6112
6113    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6114        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6115                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6116    }
6117
6118    void enableScreenAfterBoot() {
6119        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6120                SystemClock.uptimeMillis());
6121        mWindowManager.enableScreenAfterBoot();
6122
6123        synchronized (this) {
6124            updateEventDispatchingLocked();
6125        }
6126    }
6127
6128    @Override
6129    public void showBootMessage(final CharSequence msg, final boolean always) {
6130        enforceNotIsolatedCaller("showBootMessage");
6131        mWindowManager.showBootMessage(msg, always);
6132    }
6133
6134    @Override
6135    public void keyguardWaitingForActivityDrawn() {
6136        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6137        final long token = Binder.clearCallingIdentity();
6138        try {
6139            synchronized (this) {
6140                if (DEBUG_LOCKSCREEN) logLockScreen("");
6141                mWindowManager.keyguardWaitingForActivityDrawn();
6142                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6143                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6144                    updateSleepIfNeededLocked();
6145                }
6146            }
6147        } finally {
6148            Binder.restoreCallingIdentity(token);
6149        }
6150    }
6151
6152    final void finishBooting() {
6153        synchronized (this) {
6154            if (!mBootAnimationComplete) {
6155                mCallFinishBooting = true;
6156                return;
6157            }
6158            mCallFinishBooting = false;
6159        }
6160
6161        ArraySet<String> completedIsas = new ArraySet<String>();
6162        for (String abi : Build.SUPPORTED_ABIS) {
6163            Process.establishZygoteConnectionForAbi(abi);
6164            final String instructionSet = VMRuntime.getInstructionSet(abi);
6165            if (!completedIsas.contains(instructionSet)) {
6166                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6167                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6168                }
6169                completedIsas.add(instructionSet);
6170            }
6171        }
6172
6173        IntentFilter pkgFilter = new IntentFilter();
6174        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6175        pkgFilter.addDataScheme("package");
6176        mContext.registerReceiver(new BroadcastReceiver() {
6177            @Override
6178            public void onReceive(Context context, Intent intent) {
6179                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6180                if (pkgs != null) {
6181                    for (String pkg : pkgs) {
6182                        synchronized (ActivityManagerService.this) {
6183                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6184                                    0, "finished booting")) {
6185                                setResultCode(Activity.RESULT_OK);
6186                                return;
6187                            }
6188                        }
6189                    }
6190                }
6191            }
6192        }, pkgFilter);
6193
6194        // Let system services know.
6195        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6196
6197        synchronized (this) {
6198            // Ensure that any processes we had put on hold are now started
6199            // up.
6200            final int NP = mProcessesOnHold.size();
6201            if (NP > 0) {
6202                ArrayList<ProcessRecord> procs =
6203                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6204                for (int ip=0; ip<NP; ip++) {
6205                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6206                            + procs.get(ip));
6207                    startProcessLocked(procs.get(ip), "on-hold", null);
6208                }
6209            }
6210
6211            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6212                // Start looking for apps that are abusing wake locks.
6213                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6214                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6215                // Tell anyone interested that we are done booting!
6216                SystemProperties.set("sys.boot_completed", "1");
6217
6218                // And trigger dev.bootcomplete if we are not showing encryption progress
6219                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6220                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6221                    SystemProperties.set("dev.bootcomplete", "1");
6222                }
6223                for (int i=0; i<mStartedUsers.size(); i++) {
6224                    UserStartedState uss = mStartedUsers.valueAt(i);
6225                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6226                        uss.mState = UserStartedState.STATE_RUNNING;
6227                        final int userId = mStartedUsers.keyAt(i);
6228                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6229                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6230                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6231                        broadcastIntentLocked(null, null, intent, null,
6232                                new IIntentReceiver.Stub() {
6233                                    @Override
6234                                    public void performReceive(Intent intent, int resultCode,
6235                                            String data, Bundle extras, boolean ordered,
6236                                            boolean sticky, int sendingUser) {
6237                                        synchronized (ActivityManagerService.this) {
6238                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6239                                                    true, false);
6240                                        }
6241                                    }
6242                                },
6243                                0, null, null,
6244                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6245                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6246                                userId);
6247                    }
6248                }
6249                scheduleStartProfilesLocked();
6250            }
6251        }
6252    }
6253
6254    @Override
6255    public void bootAnimationComplete() {
6256        final boolean callFinishBooting;
6257        synchronized (this) {
6258            callFinishBooting = mCallFinishBooting;
6259            mBootAnimationComplete = true;
6260        }
6261        if (callFinishBooting) {
6262            finishBooting();
6263        }
6264    }
6265
6266    @Override
6267    public void systemBackupRestored() {
6268        synchronized (this) {
6269            if (mSystemReady) {
6270                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6271            } else {
6272                Slog.w(TAG, "System backup restored before system is ready");
6273            }
6274        }
6275    }
6276
6277    final void ensureBootCompleted() {
6278        boolean booting;
6279        boolean enableScreen;
6280        synchronized (this) {
6281            booting = mBooting;
6282            mBooting = false;
6283            enableScreen = !mBooted;
6284            mBooted = true;
6285        }
6286
6287        if (booting) {
6288            finishBooting();
6289        }
6290
6291        if (enableScreen) {
6292            enableScreenAfterBoot();
6293        }
6294    }
6295
6296    @Override
6297    public final void activityResumed(IBinder token) {
6298        final long origId = Binder.clearCallingIdentity();
6299        synchronized(this) {
6300            ActivityStack stack = ActivityRecord.getStackLocked(token);
6301            if (stack != null) {
6302                ActivityRecord.activityResumedLocked(token);
6303            }
6304        }
6305        Binder.restoreCallingIdentity(origId);
6306    }
6307
6308    @Override
6309    public final void activityPaused(IBinder token) {
6310        final long origId = Binder.clearCallingIdentity();
6311        synchronized(this) {
6312            ActivityStack stack = ActivityRecord.getStackLocked(token);
6313            if (stack != null) {
6314                stack.activityPausedLocked(token, false);
6315            }
6316        }
6317        Binder.restoreCallingIdentity(origId);
6318    }
6319
6320    @Override
6321    public final void activityStopped(IBinder token, Bundle icicle,
6322            PersistableBundle persistentState, CharSequence description) {
6323        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6324
6325        // Refuse possible leaked file descriptors
6326        if (icicle != null && icicle.hasFileDescriptors()) {
6327            throw new IllegalArgumentException("File descriptors passed in Bundle");
6328        }
6329
6330        final long origId = Binder.clearCallingIdentity();
6331
6332        synchronized (this) {
6333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6334            if (r != null) {
6335                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6336            }
6337        }
6338
6339        trimApplications();
6340
6341        Binder.restoreCallingIdentity(origId);
6342    }
6343
6344    @Override
6345    public final void activityDestroyed(IBinder token) {
6346        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6347        synchronized (this) {
6348            ActivityStack stack = ActivityRecord.getStackLocked(token);
6349            if (stack != null) {
6350                stack.activityDestroyedLocked(token);
6351            }
6352        }
6353    }
6354
6355    @Override
6356    public final void backgroundResourcesReleased(IBinder token) {
6357        final long origId = Binder.clearCallingIdentity();
6358        try {
6359            synchronized (this) {
6360                ActivityStack stack = ActivityRecord.getStackLocked(token);
6361                if (stack != null) {
6362                    stack.backgroundResourcesReleased();
6363                }
6364            }
6365        } finally {
6366            Binder.restoreCallingIdentity(origId);
6367        }
6368    }
6369
6370    @Override
6371    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6372        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6373    }
6374
6375    @Override
6376    public final void notifyEnterAnimationComplete(IBinder token) {
6377        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6378    }
6379
6380    @Override
6381    public String getCallingPackage(IBinder token) {
6382        synchronized (this) {
6383            ActivityRecord r = getCallingRecordLocked(token);
6384            return r != null ? r.info.packageName : null;
6385        }
6386    }
6387
6388    @Override
6389    public ComponentName getCallingActivity(IBinder token) {
6390        synchronized (this) {
6391            ActivityRecord r = getCallingRecordLocked(token);
6392            return r != null ? r.intent.getComponent() : null;
6393        }
6394    }
6395
6396    private ActivityRecord getCallingRecordLocked(IBinder token) {
6397        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6398        if (r == null) {
6399            return null;
6400        }
6401        return r.resultTo;
6402    }
6403
6404    @Override
6405    public ComponentName getActivityClassForToken(IBinder token) {
6406        synchronized(this) {
6407            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6408            if (r == null) {
6409                return null;
6410            }
6411            return r.intent.getComponent();
6412        }
6413    }
6414
6415    @Override
6416    public String getPackageForToken(IBinder token) {
6417        synchronized(this) {
6418            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6419            if (r == null) {
6420                return null;
6421            }
6422            return r.packageName;
6423        }
6424    }
6425
6426    @Override
6427    public IIntentSender getIntentSender(int type,
6428            String packageName, IBinder token, String resultWho,
6429            int requestCode, Intent[] intents, String[] resolvedTypes,
6430            int flags, Bundle options, int userId) {
6431        enforceNotIsolatedCaller("getIntentSender");
6432        // Refuse possible leaked file descriptors
6433        if (intents != null) {
6434            if (intents.length < 1) {
6435                throw new IllegalArgumentException("Intents array length must be >= 1");
6436            }
6437            for (int i=0; i<intents.length; i++) {
6438                Intent intent = intents[i];
6439                if (intent != null) {
6440                    if (intent.hasFileDescriptors()) {
6441                        throw new IllegalArgumentException("File descriptors passed in Intent");
6442                    }
6443                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6444                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6445                        throw new IllegalArgumentException(
6446                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6447                    }
6448                    intents[i] = new Intent(intent);
6449                }
6450            }
6451            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6452                throw new IllegalArgumentException(
6453                        "Intent array length does not match resolvedTypes length");
6454            }
6455        }
6456        if (options != null) {
6457            if (options.hasFileDescriptors()) {
6458                throw new IllegalArgumentException("File descriptors passed in options");
6459            }
6460        }
6461
6462        synchronized(this) {
6463            int callingUid = Binder.getCallingUid();
6464            int origUserId = userId;
6465            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6466                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6467                    ALLOW_NON_FULL, "getIntentSender", null);
6468            if (origUserId == UserHandle.USER_CURRENT) {
6469                // We don't want to evaluate this until the pending intent is
6470                // actually executed.  However, we do want to always do the
6471                // security checking for it above.
6472                userId = UserHandle.USER_CURRENT;
6473            }
6474            try {
6475                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6476                    int uid = AppGlobals.getPackageManager()
6477                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6478                    if (!UserHandle.isSameApp(callingUid, uid)) {
6479                        String msg = "Permission Denial: getIntentSender() from pid="
6480                            + Binder.getCallingPid()
6481                            + ", uid=" + Binder.getCallingUid()
6482                            + ", (need uid=" + uid + ")"
6483                            + " is not allowed to send as package " + packageName;
6484                        Slog.w(TAG, msg);
6485                        throw new SecurityException(msg);
6486                    }
6487                }
6488
6489                return getIntentSenderLocked(type, packageName, callingUid, userId,
6490                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6491
6492            } catch (RemoteException e) {
6493                throw new SecurityException(e);
6494            }
6495        }
6496    }
6497
6498    IIntentSender getIntentSenderLocked(int type, String packageName,
6499            int callingUid, int userId, IBinder token, String resultWho,
6500            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6501            Bundle options) {
6502        if (DEBUG_MU)
6503            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6504        ActivityRecord activity = null;
6505        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6506            activity = ActivityRecord.isInStackLocked(token);
6507            if (activity == null) {
6508                return null;
6509            }
6510            if (activity.finishing) {
6511                return null;
6512            }
6513        }
6514
6515        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6516        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6517        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6518        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6519                |PendingIntent.FLAG_UPDATE_CURRENT);
6520
6521        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6522                type, packageName, activity, resultWho,
6523                requestCode, intents, resolvedTypes, flags, options, userId);
6524        WeakReference<PendingIntentRecord> ref;
6525        ref = mIntentSenderRecords.get(key);
6526        PendingIntentRecord rec = ref != null ? ref.get() : null;
6527        if (rec != null) {
6528            if (!cancelCurrent) {
6529                if (updateCurrent) {
6530                    if (rec.key.requestIntent != null) {
6531                        rec.key.requestIntent.replaceExtras(intents != null ?
6532                                intents[intents.length - 1] : null);
6533                    }
6534                    if (intents != null) {
6535                        intents[intents.length-1] = rec.key.requestIntent;
6536                        rec.key.allIntents = intents;
6537                        rec.key.allResolvedTypes = resolvedTypes;
6538                    } else {
6539                        rec.key.allIntents = null;
6540                        rec.key.allResolvedTypes = null;
6541                    }
6542                }
6543                return rec;
6544            }
6545            rec.canceled = true;
6546            mIntentSenderRecords.remove(key);
6547        }
6548        if (noCreate) {
6549            return rec;
6550        }
6551        rec = new PendingIntentRecord(this, key, callingUid);
6552        mIntentSenderRecords.put(key, rec.ref);
6553        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6554            if (activity.pendingResults == null) {
6555                activity.pendingResults
6556                        = new HashSet<WeakReference<PendingIntentRecord>>();
6557            }
6558            activity.pendingResults.add(rec.ref);
6559        }
6560        return rec;
6561    }
6562
6563    @Override
6564    public void cancelIntentSender(IIntentSender sender) {
6565        if (!(sender instanceof PendingIntentRecord)) {
6566            return;
6567        }
6568        synchronized(this) {
6569            PendingIntentRecord rec = (PendingIntentRecord)sender;
6570            try {
6571                int uid = AppGlobals.getPackageManager()
6572                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6573                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6574                    String msg = "Permission Denial: cancelIntentSender() from pid="
6575                        + Binder.getCallingPid()
6576                        + ", uid=" + Binder.getCallingUid()
6577                        + " is not allowed to cancel packges "
6578                        + rec.key.packageName;
6579                    Slog.w(TAG, msg);
6580                    throw new SecurityException(msg);
6581                }
6582            } catch (RemoteException e) {
6583                throw new SecurityException(e);
6584            }
6585            cancelIntentSenderLocked(rec, true);
6586        }
6587    }
6588
6589    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6590        rec.canceled = true;
6591        mIntentSenderRecords.remove(rec.key);
6592        if (cleanActivity && rec.key.activity != null) {
6593            rec.key.activity.pendingResults.remove(rec.ref);
6594        }
6595    }
6596
6597    @Override
6598    public String getPackageForIntentSender(IIntentSender pendingResult) {
6599        if (!(pendingResult instanceof PendingIntentRecord)) {
6600            return null;
6601        }
6602        try {
6603            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6604            return res.key.packageName;
6605        } catch (ClassCastException e) {
6606        }
6607        return null;
6608    }
6609
6610    @Override
6611    public int getUidForIntentSender(IIntentSender sender) {
6612        if (sender instanceof PendingIntentRecord) {
6613            try {
6614                PendingIntentRecord res = (PendingIntentRecord)sender;
6615                return res.uid;
6616            } catch (ClassCastException e) {
6617            }
6618        }
6619        return -1;
6620    }
6621
6622    @Override
6623    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6624        if (!(pendingResult instanceof PendingIntentRecord)) {
6625            return false;
6626        }
6627        try {
6628            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6629            if (res.key.allIntents == null) {
6630                return false;
6631            }
6632            for (int i=0; i<res.key.allIntents.length; i++) {
6633                Intent intent = res.key.allIntents[i];
6634                if (intent.getPackage() != null && intent.getComponent() != null) {
6635                    return false;
6636                }
6637            }
6638            return true;
6639        } catch (ClassCastException e) {
6640        }
6641        return false;
6642    }
6643
6644    @Override
6645    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6646        if (!(pendingResult instanceof PendingIntentRecord)) {
6647            return false;
6648        }
6649        try {
6650            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6651            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6652                return true;
6653            }
6654            return false;
6655        } catch (ClassCastException e) {
6656        }
6657        return false;
6658    }
6659
6660    @Override
6661    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6662        if (!(pendingResult instanceof PendingIntentRecord)) {
6663            return null;
6664        }
6665        try {
6666            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6667            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6668        } catch (ClassCastException e) {
6669        }
6670        return null;
6671    }
6672
6673    @Override
6674    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6675        if (!(pendingResult instanceof PendingIntentRecord)) {
6676            return null;
6677        }
6678        try {
6679            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6680            Intent intent = res.key.requestIntent;
6681            if (intent != null) {
6682                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6683                        || res.lastTagPrefix.equals(prefix))) {
6684                    return res.lastTag;
6685                }
6686                res.lastTagPrefix = prefix;
6687                StringBuilder sb = new StringBuilder(128);
6688                if (prefix != null) {
6689                    sb.append(prefix);
6690                }
6691                if (intent.getAction() != null) {
6692                    sb.append(intent.getAction());
6693                } else if (intent.getComponent() != null) {
6694                    intent.getComponent().appendShortString(sb);
6695                } else {
6696                    sb.append("?");
6697                }
6698                return res.lastTag = sb.toString();
6699            }
6700        } catch (ClassCastException e) {
6701        }
6702        return null;
6703    }
6704
6705    @Override
6706    public void setProcessLimit(int max) {
6707        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6708                "setProcessLimit()");
6709        synchronized (this) {
6710            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6711            mProcessLimitOverride = max;
6712        }
6713        trimApplications();
6714    }
6715
6716    @Override
6717    public int getProcessLimit() {
6718        synchronized (this) {
6719            return mProcessLimitOverride;
6720        }
6721    }
6722
6723    void foregroundTokenDied(ForegroundToken token) {
6724        synchronized (ActivityManagerService.this) {
6725            synchronized (mPidsSelfLocked) {
6726                ForegroundToken cur
6727                    = mForegroundProcesses.get(token.pid);
6728                if (cur != token) {
6729                    return;
6730                }
6731                mForegroundProcesses.remove(token.pid);
6732                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6733                if (pr == null) {
6734                    return;
6735                }
6736                pr.forcingToForeground = null;
6737                updateProcessForegroundLocked(pr, false, false);
6738            }
6739            updateOomAdjLocked();
6740        }
6741    }
6742
6743    @Override
6744    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6745        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6746                "setProcessForeground()");
6747        synchronized(this) {
6748            boolean changed = false;
6749
6750            synchronized (mPidsSelfLocked) {
6751                ProcessRecord pr = mPidsSelfLocked.get(pid);
6752                if (pr == null && isForeground) {
6753                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6754                    return;
6755                }
6756                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6757                if (oldToken != null) {
6758                    oldToken.token.unlinkToDeath(oldToken, 0);
6759                    mForegroundProcesses.remove(pid);
6760                    if (pr != null) {
6761                        pr.forcingToForeground = null;
6762                    }
6763                    changed = true;
6764                }
6765                if (isForeground && token != null) {
6766                    ForegroundToken newToken = new ForegroundToken() {
6767                        @Override
6768                        public void binderDied() {
6769                            foregroundTokenDied(this);
6770                        }
6771                    };
6772                    newToken.pid = pid;
6773                    newToken.token = token;
6774                    try {
6775                        token.linkToDeath(newToken, 0);
6776                        mForegroundProcesses.put(pid, newToken);
6777                        pr.forcingToForeground = token;
6778                        changed = true;
6779                    } catch (RemoteException e) {
6780                        // If the process died while doing this, we will later
6781                        // do the cleanup with the process death link.
6782                    }
6783                }
6784            }
6785
6786            if (changed) {
6787                updateOomAdjLocked();
6788            }
6789        }
6790    }
6791
6792    // =========================================================
6793    // PERMISSIONS
6794    // =========================================================
6795
6796    static class PermissionController extends IPermissionController.Stub {
6797        ActivityManagerService mActivityManagerService;
6798        PermissionController(ActivityManagerService activityManagerService) {
6799            mActivityManagerService = activityManagerService;
6800        }
6801
6802        @Override
6803        public boolean checkPermission(String permission, int pid, int uid) {
6804            return mActivityManagerService.checkPermission(permission, pid,
6805                    uid) == PackageManager.PERMISSION_GRANTED;
6806        }
6807    }
6808
6809    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6810        @Override
6811        public int checkComponentPermission(String permission, int pid, int uid,
6812                int owningUid, boolean exported) {
6813            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6814                    owningUid, exported);
6815        }
6816
6817        @Override
6818        public Object getAMSLock() {
6819            return ActivityManagerService.this;
6820        }
6821    }
6822
6823    /**
6824     * This can be called with or without the global lock held.
6825     */
6826    int checkComponentPermission(String permission, int pid, int uid,
6827            int owningUid, boolean exported) {
6828        if (pid == MY_PID) {
6829            return PackageManager.PERMISSION_GRANTED;
6830        }
6831        return ActivityManager.checkComponentPermission(permission, uid,
6832                owningUid, exported);
6833    }
6834
6835    /**
6836     * As the only public entry point for permissions checking, this method
6837     * can enforce the semantic that requesting a check on a null global
6838     * permission is automatically denied.  (Internally a null permission
6839     * string is used when calling {@link #checkComponentPermission} in cases
6840     * when only uid-based security is needed.)
6841     *
6842     * This can be called with or without the global lock held.
6843     */
6844    @Override
6845    public int checkPermission(String permission, int pid, int uid) {
6846        if (permission == null) {
6847            return PackageManager.PERMISSION_DENIED;
6848        }
6849        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6850    }
6851
6852    @Override
6853    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6854        if (permission == null) {
6855            return PackageManager.PERMISSION_DENIED;
6856        }
6857
6858        // We might be performing an operation on behalf of an indirect binder
6859        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6860        // client identity accordingly before proceeding.
6861        Identity tlsIdentity = sCallerIdentity.get();
6862        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6863            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6864                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6865            uid = tlsIdentity.uid;
6866            pid = tlsIdentity.pid;
6867        }
6868
6869        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6870    }
6871
6872    /**
6873     * Binder IPC calls go through the public entry point.
6874     * This can be called with or without the global lock held.
6875     */
6876    int checkCallingPermission(String permission) {
6877        return checkPermission(permission,
6878                Binder.getCallingPid(),
6879                UserHandle.getAppId(Binder.getCallingUid()));
6880    }
6881
6882    /**
6883     * This can be called with or without the global lock held.
6884     */
6885    void enforceCallingPermission(String permission, String func) {
6886        if (checkCallingPermission(permission)
6887                == PackageManager.PERMISSION_GRANTED) {
6888            return;
6889        }
6890
6891        String msg = "Permission Denial: " + func + " from pid="
6892                + Binder.getCallingPid()
6893                + ", uid=" + Binder.getCallingUid()
6894                + " requires " + permission;
6895        Slog.w(TAG, msg);
6896        throw new SecurityException(msg);
6897    }
6898
6899    /**
6900     * Determine if UID is holding permissions required to access {@link Uri} in
6901     * the given {@link ProviderInfo}. Final permission checking is always done
6902     * in {@link ContentProvider}.
6903     */
6904    private final boolean checkHoldingPermissionsLocked(
6905            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6906        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6907                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6908        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6909            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6910                    != PERMISSION_GRANTED) {
6911                return false;
6912            }
6913        }
6914        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6915    }
6916
6917    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6918            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6919        if (pi.applicationInfo.uid == uid) {
6920            return true;
6921        } else if (!pi.exported) {
6922            return false;
6923        }
6924
6925        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6926        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6927        try {
6928            // check if target holds top-level <provider> permissions
6929            if (!readMet && pi.readPermission != null && considerUidPermissions
6930                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6931                readMet = true;
6932            }
6933            if (!writeMet && pi.writePermission != null && considerUidPermissions
6934                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6935                writeMet = true;
6936            }
6937
6938            // track if unprotected read/write is allowed; any denied
6939            // <path-permission> below removes this ability
6940            boolean allowDefaultRead = pi.readPermission == null;
6941            boolean allowDefaultWrite = pi.writePermission == null;
6942
6943            // check if target holds any <path-permission> that match uri
6944            final PathPermission[] pps = pi.pathPermissions;
6945            if (pps != null) {
6946                final String path = grantUri.uri.getPath();
6947                int i = pps.length;
6948                while (i > 0 && (!readMet || !writeMet)) {
6949                    i--;
6950                    PathPermission pp = pps[i];
6951                    if (pp.match(path)) {
6952                        if (!readMet) {
6953                            final String pprperm = pp.getReadPermission();
6954                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6955                                    + pprperm + " for " + pp.getPath()
6956                                    + ": match=" + pp.match(path)
6957                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6958                            if (pprperm != null) {
6959                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6960                                        == PERMISSION_GRANTED) {
6961                                    readMet = true;
6962                                } else {
6963                                    allowDefaultRead = false;
6964                                }
6965                            }
6966                        }
6967                        if (!writeMet) {
6968                            final String ppwperm = pp.getWritePermission();
6969                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6970                                    + ppwperm + " for " + pp.getPath()
6971                                    + ": match=" + pp.match(path)
6972                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6973                            if (ppwperm != null) {
6974                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6975                                        == PERMISSION_GRANTED) {
6976                                    writeMet = true;
6977                                } else {
6978                                    allowDefaultWrite = false;
6979                                }
6980                            }
6981                        }
6982                    }
6983                }
6984            }
6985
6986            // grant unprotected <provider> read/write, if not blocked by
6987            // <path-permission> above
6988            if (allowDefaultRead) readMet = true;
6989            if (allowDefaultWrite) writeMet = true;
6990
6991        } catch (RemoteException e) {
6992            return false;
6993        }
6994
6995        return readMet && writeMet;
6996    }
6997
6998    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6999        ProviderInfo pi = null;
7000        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7001        if (cpr != null) {
7002            pi = cpr.info;
7003        } else {
7004            try {
7005                pi = AppGlobals.getPackageManager().resolveContentProvider(
7006                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7007            } catch (RemoteException ex) {
7008            }
7009        }
7010        return pi;
7011    }
7012
7013    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7014        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7015        if (targetUris != null) {
7016            return targetUris.get(grantUri);
7017        }
7018        return null;
7019    }
7020
7021    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7022            String targetPkg, int targetUid, GrantUri grantUri) {
7023        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7024        if (targetUris == null) {
7025            targetUris = Maps.newArrayMap();
7026            mGrantedUriPermissions.put(targetUid, targetUris);
7027        }
7028
7029        UriPermission perm = targetUris.get(grantUri);
7030        if (perm == null) {
7031            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7032            targetUris.put(grantUri, perm);
7033        }
7034
7035        return perm;
7036    }
7037
7038    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7039            final int modeFlags) {
7040        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7041        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7042                : UriPermission.STRENGTH_OWNED;
7043
7044        // Root gets to do everything.
7045        if (uid == 0) {
7046            return true;
7047        }
7048
7049        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7050        if (perms == null) return false;
7051
7052        // First look for exact match
7053        final UriPermission exactPerm = perms.get(grantUri);
7054        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7055            return true;
7056        }
7057
7058        // No exact match, look for prefixes
7059        final int N = perms.size();
7060        for (int i = 0; i < N; i++) {
7061            final UriPermission perm = perms.valueAt(i);
7062            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7063                    && perm.getStrength(modeFlags) >= minStrength) {
7064                return true;
7065            }
7066        }
7067
7068        return false;
7069    }
7070
7071    /**
7072     * @param uri This uri must NOT contain an embedded userId.
7073     * @param userId The userId in which the uri is to be resolved.
7074     */
7075    @Override
7076    public int checkUriPermission(Uri uri, int pid, int uid,
7077            final int modeFlags, int userId, IBinder callerToken) {
7078        enforceNotIsolatedCaller("checkUriPermission");
7079
7080        // Another redirected-binder-call permissions check as in
7081        // {@link checkPermissionWithToken}.
7082        Identity tlsIdentity = sCallerIdentity.get();
7083        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7084            uid = tlsIdentity.uid;
7085            pid = tlsIdentity.pid;
7086        }
7087
7088        // Our own process gets to do everything.
7089        if (pid == MY_PID) {
7090            return PackageManager.PERMISSION_GRANTED;
7091        }
7092        synchronized (this) {
7093            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7094                    ? PackageManager.PERMISSION_GRANTED
7095                    : PackageManager.PERMISSION_DENIED;
7096        }
7097    }
7098
7099    /**
7100     * Check if the targetPkg can be granted permission to access uri by
7101     * the callingUid using the given modeFlags.  Throws a security exception
7102     * if callingUid is not allowed to do this.  Returns the uid of the target
7103     * if the URI permission grant should be performed; returns -1 if it is not
7104     * needed (for example targetPkg already has permission to access the URI).
7105     * If you already know the uid of the target, you can supply it in
7106     * lastTargetUid else set that to -1.
7107     */
7108    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7109            final int modeFlags, int lastTargetUid) {
7110        if (!Intent.isAccessUriMode(modeFlags)) {
7111            return -1;
7112        }
7113
7114        if (targetPkg != null) {
7115            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7116                    "Checking grant " + targetPkg + " permission to " + grantUri);
7117        }
7118
7119        final IPackageManager pm = AppGlobals.getPackageManager();
7120
7121        // If this is not a content: uri, we can't do anything with it.
7122        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7123            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7124                    "Can't grant URI permission for non-content URI: " + grantUri);
7125            return -1;
7126        }
7127
7128        final String authority = grantUri.uri.getAuthority();
7129        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7130        if (pi == null) {
7131            Slog.w(TAG, "No content provider found for permission check: " +
7132                    grantUri.uri.toSafeString());
7133            return -1;
7134        }
7135
7136        int targetUid = lastTargetUid;
7137        if (targetUid < 0 && targetPkg != null) {
7138            try {
7139                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7140                if (targetUid < 0) {
7141                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7142                            "Can't grant URI permission no uid for: " + targetPkg);
7143                    return -1;
7144                }
7145            } catch (RemoteException ex) {
7146                return -1;
7147            }
7148        }
7149
7150        if (targetUid >= 0) {
7151            // First...  does the target actually need this permission?
7152            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7153                // No need to grant the target this permission.
7154                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7155                        "Target " + targetPkg + " already has full permission to " + grantUri);
7156                return -1;
7157            }
7158        } else {
7159            // First...  there is no target package, so can anyone access it?
7160            boolean allowed = pi.exported;
7161            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7162                if (pi.readPermission != null) {
7163                    allowed = false;
7164                }
7165            }
7166            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7167                if (pi.writePermission != null) {
7168                    allowed = false;
7169                }
7170            }
7171            if (allowed) {
7172                return -1;
7173            }
7174        }
7175
7176        /* There is a special cross user grant if:
7177         * - The target is on another user.
7178         * - Apps on the current user can access the uri without any uid permissions.
7179         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7180         * grant uri permissions.
7181         */
7182        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7183                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7184                modeFlags, false /*without considering the uid permissions*/);
7185
7186        // Second...  is the provider allowing granting of URI permissions?
7187        if (!specialCrossUserGrant) {
7188            if (!pi.grantUriPermissions) {
7189                throw new SecurityException("Provider " + pi.packageName
7190                        + "/" + pi.name
7191                        + " does not allow granting of Uri permissions (uri "
7192                        + grantUri + ")");
7193            }
7194            if (pi.uriPermissionPatterns != null) {
7195                final int N = pi.uriPermissionPatterns.length;
7196                boolean allowed = false;
7197                for (int i=0; i<N; i++) {
7198                    if (pi.uriPermissionPatterns[i] != null
7199                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7200                        allowed = true;
7201                        break;
7202                    }
7203                }
7204                if (!allowed) {
7205                    throw new SecurityException("Provider " + pi.packageName
7206                            + "/" + pi.name
7207                            + " does not allow granting of permission to path of Uri "
7208                            + grantUri);
7209                }
7210            }
7211        }
7212
7213        // Third...  does the caller itself have permission to access
7214        // this uri?
7215        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7216            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7217                // Require they hold a strong enough Uri permission
7218                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7219                    throw new SecurityException("Uid " + callingUid
7220                            + " does not have permission to uri " + grantUri);
7221                }
7222            }
7223        }
7224        return targetUid;
7225    }
7226
7227    /**
7228     * @param uri This uri must NOT contain an embedded userId.
7229     * @param userId The userId in which the uri is to be resolved.
7230     */
7231    @Override
7232    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7233            final int modeFlags, int userId) {
7234        enforceNotIsolatedCaller("checkGrantUriPermission");
7235        synchronized(this) {
7236            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7237                    new GrantUri(userId, uri, false), modeFlags, -1);
7238        }
7239    }
7240
7241    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7242            final int modeFlags, UriPermissionOwner owner) {
7243        if (!Intent.isAccessUriMode(modeFlags)) {
7244            return;
7245        }
7246
7247        // So here we are: the caller has the assumed permission
7248        // to the uri, and the target doesn't.  Let's now give this to
7249        // the target.
7250
7251        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7252                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7253
7254        final String authority = grantUri.uri.getAuthority();
7255        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7256        if (pi == null) {
7257            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7258            return;
7259        }
7260
7261        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7262            grantUri.prefix = true;
7263        }
7264        final UriPermission perm = findOrCreateUriPermissionLocked(
7265                pi.packageName, targetPkg, targetUid, grantUri);
7266        perm.grantModes(modeFlags, owner);
7267    }
7268
7269    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7270            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7271        if (targetPkg == null) {
7272            throw new NullPointerException("targetPkg");
7273        }
7274        int targetUid;
7275        final IPackageManager pm = AppGlobals.getPackageManager();
7276        try {
7277            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7278        } catch (RemoteException ex) {
7279            return;
7280        }
7281
7282        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7283                targetUid);
7284        if (targetUid < 0) {
7285            return;
7286        }
7287
7288        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7289                owner);
7290    }
7291
7292    static class NeededUriGrants extends ArrayList<GrantUri> {
7293        final String targetPkg;
7294        final int targetUid;
7295        final int flags;
7296
7297        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7298            this.targetPkg = targetPkg;
7299            this.targetUid = targetUid;
7300            this.flags = flags;
7301        }
7302    }
7303
7304    /**
7305     * Like checkGrantUriPermissionLocked, but takes an Intent.
7306     */
7307    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7308            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7309        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7310                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7311                + " clip=" + (intent != null ? intent.getClipData() : null)
7312                + " from " + intent + "; flags=0x"
7313                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7314
7315        if (targetPkg == null) {
7316            throw new NullPointerException("targetPkg");
7317        }
7318
7319        if (intent == null) {
7320            return null;
7321        }
7322        Uri data = intent.getData();
7323        ClipData clip = intent.getClipData();
7324        if (data == null && clip == null) {
7325            return null;
7326        }
7327        // Default userId for uris in the intent (if they don't specify it themselves)
7328        int contentUserHint = intent.getContentUserHint();
7329        if (contentUserHint == UserHandle.USER_CURRENT) {
7330            contentUserHint = UserHandle.getUserId(callingUid);
7331        }
7332        final IPackageManager pm = AppGlobals.getPackageManager();
7333        int targetUid;
7334        if (needed != null) {
7335            targetUid = needed.targetUid;
7336        } else {
7337            try {
7338                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7339            } catch (RemoteException ex) {
7340                return null;
7341            }
7342            if (targetUid < 0) {
7343                if (DEBUG_URI_PERMISSION) {
7344                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7345                            + " on user " + targetUserId);
7346                }
7347                return null;
7348            }
7349        }
7350        if (data != null) {
7351            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7352            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7353                    targetUid);
7354            if (targetUid > 0) {
7355                if (needed == null) {
7356                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7357                }
7358                needed.add(grantUri);
7359            }
7360        }
7361        if (clip != null) {
7362            for (int i=0; i<clip.getItemCount(); i++) {
7363                Uri uri = clip.getItemAt(i).getUri();
7364                if (uri != null) {
7365                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7366                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7367                            targetUid);
7368                    if (targetUid > 0) {
7369                        if (needed == null) {
7370                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7371                        }
7372                        needed.add(grantUri);
7373                    }
7374                } else {
7375                    Intent clipIntent = clip.getItemAt(i).getIntent();
7376                    if (clipIntent != null) {
7377                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7378                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7379                        if (newNeeded != null) {
7380                            needed = newNeeded;
7381                        }
7382                    }
7383                }
7384            }
7385        }
7386
7387        return needed;
7388    }
7389
7390    /**
7391     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7392     */
7393    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7394            UriPermissionOwner owner) {
7395        if (needed != null) {
7396            for (int i=0; i<needed.size(); i++) {
7397                GrantUri grantUri = needed.get(i);
7398                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7399                        grantUri, needed.flags, owner);
7400            }
7401        }
7402    }
7403
7404    void grantUriPermissionFromIntentLocked(int callingUid,
7405            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7406        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7407                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7408        if (needed == null) {
7409            return;
7410        }
7411
7412        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7413    }
7414
7415    /**
7416     * @param uri This uri must NOT contain an embedded userId.
7417     * @param userId The userId in which the uri is to be resolved.
7418     */
7419    @Override
7420    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7421            final int modeFlags, int userId) {
7422        enforceNotIsolatedCaller("grantUriPermission");
7423        GrantUri grantUri = new GrantUri(userId, uri, false);
7424        synchronized(this) {
7425            final ProcessRecord r = getRecordForAppLocked(caller);
7426            if (r == null) {
7427                throw new SecurityException("Unable to find app for caller "
7428                        + caller
7429                        + " when granting permission to uri " + grantUri);
7430            }
7431            if (targetPkg == null) {
7432                throw new IllegalArgumentException("null target");
7433            }
7434            if (grantUri == null) {
7435                throw new IllegalArgumentException("null uri");
7436            }
7437
7438            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7439                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7440                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7441                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7442
7443            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7444                    UserHandle.getUserId(r.uid));
7445        }
7446    }
7447
7448    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7449        if (perm.modeFlags == 0) {
7450            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7451                    perm.targetUid);
7452            if (perms != null) {
7453                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7454                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7455
7456                perms.remove(perm.uri);
7457                if (perms.isEmpty()) {
7458                    mGrantedUriPermissions.remove(perm.targetUid);
7459                }
7460            }
7461        }
7462    }
7463
7464    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7465        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7466
7467        final IPackageManager pm = AppGlobals.getPackageManager();
7468        final String authority = grantUri.uri.getAuthority();
7469        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7470        if (pi == null) {
7471            Slog.w(TAG, "No content provider found for permission revoke: "
7472                    + grantUri.toSafeString());
7473            return;
7474        }
7475
7476        // Does the caller have this permission on the URI?
7477        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7478            // If they don't have direct access to the URI, then revoke any
7479            // ownerless URI permissions that have been granted to them.
7480            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7481            if (perms != null) {
7482                boolean persistChanged = false;
7483                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7484                    final UriPermission perm = it.next();
7485                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7486                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7487                        if (DEBUG_URI_PERMISSION)
7488                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7489                                    " permission to " + perm.uri);
7490                        persistChanged |= perm.revokeModes(
7491                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7492                        if (perm.modeFlags == 0) {
7493                            it.remove();
7494                        }
7495                    }
7496                }
7497                if (perms.isEmpty()) {
7498                    mGrantedUriPermissions.remove(callingUid);
7499                }
7500                if (persistChanged) {
7501                    schedulePersistUriGrants();
7502                }
7503            }
7504            return;
7505        }
7506
7507        boolean persistChanged = false;
7508
7509        // Go through all of the permissions and remove any that match.
7510        int N = mGrantedUriPermissions.size();
7511        for (int i = 0; i < N; i++) {
7512            final int targetUid = mGrantedUriPermissions.keyAt(i);
7513            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7514
7515            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7516                final UriPermission perm = it.next();
7517                if (perm.uri.sourceUserId == grantUri.sourceUserId
7518                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7519                    if (DEBUG_URI_PERMISSION)
7520                        Slog.v(TAG,
7521                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7522                    persistChanged |= perm.revokeModes(
7523                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7524                    if (perm.modeFlags == 0) {
7525                        it.remove();
7526                    }
7527                }
7528            }
7529
7530            if (perms.isEmpty()) {
7531                mGrantedUriPermissions.remove(targetUid);
7532                N--;
7533                i--;
7534            }
7535        }
7536
7537        if (persistChanged) {
7538            schedulePersistUriGrants();
7539        }
7540    }
7541
7542    /**
7543     * @param uri This uri must NOT contain an embedded userId.
7544     * @param userId The userId in which the uri is to be resolved.
7545     */
7546    @Override
7547    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7548            int userId) {
7549        enforceNotIsolatedCaller("revokeUriPermission");
7550        synchronized(this) {
7551            final ProcessRecord r = getRecordForAppLocked(caller);
7552            if (r == null) {
7553                throw new SecurityException("Unable to find app for caller "
7554                        + caller
7555                        + " when revoking permission to uri " + uri);
7556            }
7557            if (uri == null) {
7558                Slog.w(TAG, "revokeUriPermission: null uri");
7559                return;
7560            }
7561
7562            if (!Intent.isAccessUriMode(modeFlags)) {
7563                return;
7564            }
7565
7566            final IPackageManager pm = AppGlobals.getPackageManager();
7567            final String authority = uri.getAuthority();
7568            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7569            if (pi == null) {
7570                Slog.w(TAG, "No content provider found for permission revoke: "
7571                        + uri.toSafeString());
7572                return;
7573            }
7574
7575            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7576        }
7577    }
7578
7579    /**
7580     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7581     * given package.
7582     *
7583     * @param packageName Package name to match, or {@code null} to apply to all
7584     *            packages.
7585     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7586     *            to all users.
7587     * @param persistable If persistable grants should be removed.
7588     */
7589    private void removeUriPermissionsForPackageLocked(
7590            String packageName, int userHandle, boolean persistable) {
7591        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7592            throw new IllegalArgumentException("Must narrow by either package or user");
7593        }
7594
7595        boolean persistChanged = false;
7596
7597        int N = mGrantedUriPermissions.size();
7598        for (int i = 0; i < N; i++) {
7599            final int targetUid = mGrantedUriPermissions.keyAt(i);
7600            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7601
7602            // Only inspect grants matching user
7603            if (userHandle == UserHandle.USER_ALL
7604                    || userHandle == UserHandle.getUserId(targetUid)) {
7605                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7606                    final UriPermission perm = it.next();
7607
7608                    // Only inspect grants matching package
7609                    if (packageName == null || perm.sourcePkg.equals(packageName)
7610                            || perm.targetPkg.equals(packageName)) {
7611                        persistChanged |= perm.revokeModes(persistable
7612                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7613
7614                        // Only remove when no modes remain; any persisted grants
7615                        // will keep this alive.
7616                        if (perm.modeFlags == 0) {
7617                            it.remove();
7618                        }
7619                    }
7620                }
7621
7622                if (perms.isEmpty()) {
7623                    mGrantedUriPermissions.remove(targetUid);
7624                    N--;
7625                    i--;
7626                }
7627            }
7628        }
7629
7630        if (persistChanged) {
7631            schedulePersistUriGrants();
7632        }
7633    }
7634
7635    @Override
7636    public IBinder newUriPermissionOwner(String name) {
7637        enforceNotIsolatedCaller("newUriPermissionOwner");
7638        synchronized(this) {
7639            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7640            return owner.getExternalTokenLocked();
7641        }
7642    }
7643
7644    /**
7645     * @param uri This uri must NOT contain an embedded userId.
7646     * @param sourceUserId The userId in which the uri is to be resolved.
7647     * @param targetUserId The userId of the app that receives the grant.
7648     */
7649    @Override
7650    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7651            final int modeFlags, int sourceUserId, int targetUserId) {
7652        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7653                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7654        synchronized(this) {
7655            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7656            if (owner == null) {
7657                throw new IllegalArgumentException("Unknown owner: " + token);
7658            }
7659            if (fromUid != Binder.getCallingUid()) {
7660                if (Binder.getCallingUid() != Process.myUid()) {
7661                    // Only system code can grant URI permissions on behalf
7662                    // of other users.
7663                    throw new SecurityException("nice try");
7664                }
7665            }
7666            if (targetPkg == null) {
7667                throw new IllegalArgumentException("null target");
7668            }
7669            if (uri == null) {
7670                throw new IllegalArgumentException("null uri");
7671            }
7672
7673            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7674                    modeFlags, owner, targetUserId);
7675        }
7676    }
7677
7678    /**
7679     * @param uri This uri must NOT contain an embedded userId.
7680     * @param userId The userId in which the uri is to be resolved.
7681     */
7682    @Override
7683    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7684        synchronized(this) {
7685            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7686            if (owner == null) {
7687                throw new IllegalArgumentException("Unknown owner: " + token);
7688            }
7689
7690            if (uri == null) {
7691                owner.removeUriPermissionsLocked(mode);
7692            } else {
7693                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7694            }
7695        }
7696    }
7697
7698    private void schedulePersistUriGrants() {
7699        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7700            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7701                    10 * DateUtils.SECOND_IN_MILLIS);
7702        }
7703    }
7704
7705    private void writeGrantedUriPermissions() {
7706        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7707
7708        // Snapshot permissions so we can persist without lock
7709        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7710        synchronized (this) {
7711            final int size = mGrantedUriPermissions.size();
7712            for (int i = 0; i < size; i++) {
7713                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7714                for (UriPermission perm : perms.values()) {
7715                    if (perm.persistedModeFlags != 0) {
7716                        persist.add(perm.snapshot());
7717                    }
7718                }
7719            }
7720        }
7721
7722        FileOutputStream fos = null;
7723        try {
7724            fos = mGrantFile.startWrite();
7725
7726            XmlSerializer out = new FastXmlSerializer();
7727            out.setOutput(fos, "utf-8");
7728            out.startDocument(null, true);
7729            out.startTag(null, TAG_URI_GRANTS);
7730            for (UriPermission.Snapshot perm : persist) {
7731                out.startTag(null, TAG_URI_GRANT);
7732                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7733                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7734                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7735                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7736                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7737                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7738                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7739                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7740                out.endTag(null, TAG_URI_GRANT);
7741            }
7742            out.endTag(null, TAG_URI_GRANTS);
7743            out.endDocument();
7744
7745            mGrantFile.finishWrite(fos);
7746        } catch (IOException e) {
7747            if (fos != null) {
7748                mGrantFile.failWrite(fos);
7749            }
7750        }
7751    }
7752
7753    private void readGrantedUriPermissionsLocked() {
7754        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7755
7756        final long now = System.currentTimeMillis();
7757
7758        FileInputStream fis = null;
7759        try {
7760            fis = mGrantFile.openRead();
7761            final XmlPullParser in = Xml.newPullParser();
7762            in.setInput(fis, null);
7763
7764            int type;
7765            while ((type = in.next()) != END_DOCUMENT) {
7766                final String tag = in.getName();
7767                if (type == START_TAG) {
7768                    if (TAG_URI_GRANT.equals(tag)) {
7769                        final int sourceUserId;
7770                        final int targetUserId;
7771                        final int userHandle = readIntAttribute(in,
7772                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7773                        if (userHandle != UserHandle.USER_NULL) {
7774                            // For backwards compatibility.
7775                            sourceUserId = userHandle;
7776                            targetUserId = userHandle;
7777                        } else {
7778                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7779                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7780                        }
7781                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7782                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7783                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7784                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7785                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7786                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7787
7788                        // Sanity check that provider still belongs to source package
7789                        final ProviderInfo pi = getProviderInfoLocked(
7790                                uri.getAuthority(), sourceUserId);
7791                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7792                            int targetUid = -1;
7793                            try {
7794                                targetUid = AppGlobals.getPackageManager()
7795                                        .getPackageUid(targetPkg, targetUserId);
7796                            } catch (RemoteException e) {
7797                            }
7798                            if (targetUid != -1) {
7799                                final UriPermission perm = findOrCreateUriPermissionLocked(
7800                                        sourcePkg, targetPkg, targetUid,
7801                                        new GrantUri(sourceUserId, uri, prefix));
7802                                perm.initPersistedModes(modeFlags, createdTime);
7803                            }
7804                        } else {
7805                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7806                                    + " but instead found " + pi);
7807                        }
7808                    }
7809                }
7810            }
7811        } catch (FileNotFoundException e) {
7812            // Missing grants is okay
7813        } catch (IOException e) {
7814            Slog.wtf(TAG, "Failed reading Uri grants", e);
7815        } catch (XmlPullParserException e) {
7816            Slog.wtf(TAG, "Failed reading Uri grants", e);
7817        } finally {
7818            IoUtils.closeQuietly(fis);
7819        }
7820    }
7821
7822    /**
7823     * @param uri This uri must NOT contain an embedded userId.
7824     * @param userId The userId in which the uri is to be resolved.
7825     */
7826    @Override
7827    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7828        enforceNotIsolatedCaller("takePersistableUriPermission");
7829
7830        Preconditions.checkFlagsArgument(modeFlags,
7831                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7832
7833        synchronized (this) {
7834            final int callingUid = Binder.getCallingUid();
7835            boolean persistChanged = false;
7836            GrantUri grantUri = new GrantUri(userId, uri, false);
7837
7838            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7839                    new GrantUri(userId, uri, false));
7840            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7841                    new GrantUri(userId, uri, true));
7842
7843            final boolean exactValid = (exactPerm != null)
7844                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7845            final boolean prefixValid = (prefixPerm != null)
7846                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7847
7848            if (!(exactValid || prefixValid)) {
7849                throw new SecurityException("No persistable permission grants found for UID "
7850                        + callingUid + " and Uri " + grantUri.toSafeString());
7851            }
7852
7853            if (exactValid) {
7854                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7855            }
7856            if (prefixValid) {
7857                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7858            }
7859
7860            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7861
7862            if (persistChanged) {
7863                schedulePersistUriGrants();
7864            }
7865        }
7866    }
7867
7868    /**
7869     * @param uri This uri must NOT contain an embedded userId.
7870     * @param userId The userId in which the uri is to be resolved.
7871     */
7872    @Override
7873    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7874        enforceNotIsolatedCaller("releasePersistableUriPermission");
7875
7876        Preconditions.checkFlagsArgument(modeFlags,
7877                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7878
7879        synchronized (this) {
7880            final int callingUid = Binder.getCallingUid();
7881            boolean persistChanged = false;
7882
7883            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7884                    new GrantUri(userId, uri, false));
7885            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7886                    new GrantUri(userId, uri, true));
7887            if (exactPerm == null && prefixPerm == null) {
7888                throw new SecurityException("No permission grants found for UID " + callingUid
7889                        + " and Uri " + uri.toSafeString());
7890            }
7891
7892            if (exactPerm != null) {
7893                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7894                removeUriPermissionIfNeededLocked(exactPerm);
7895            }
7896            if (prefixPerm != null) {
7897                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7898                removeUriPermissionIfNeededLocked(prefixPerm);
7899            }
7900
7901            if (persistChanged) {
7902                schedulePersistUriGrants();
7903            }
7904        }
7905    }
7906
7907    /**
7908     * Prune any older {@link UriPermission} for the given UID until outstanding
7909     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7910     *
7911     * @return if any mutations occured that require persisting.
7912     */
7913    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7914        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7915        if (perms == null) return false;
7916        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7917
7918        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7919        for (UriPermission perm : perms.values()) {
7920            if (perm.persistedModeFlags != 0) {
7921                persisted.add(perm);
7922            }
7923        }
7924
7925        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7926        if (trimCount <= 0) return false;
7927
7928        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7929        for (int i = 0; i < trimCount; i++) {
7930            final UriPermission perm = persisted.get(i);
7931
7932            if (DEBUG_URI_PERMISSION) {
7933                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7934            }
7935
7936            perm.releasePersistableModes(~0);
7937            removeUriPermissionIfNeededLocked(perm);
7938        }
7939
7940        return true;
7941    }
7942
7943    @Override
7944    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7945            String packageName, boolean incoming) {
7946        enforceNotIsolatedCaller("getPersistedUriPermissions");
7947        Preconditions.checkNotNull(packageName, "packageName");
7948
7949        final int callingUid = Binder.getCallingUid();
7950        final IPackageManager pm = AppGlobals.getPackageManager();
7951        try {
7952            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7953            if (packageUid != callingUid) {
7954                throw new SecurityException(
7955                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7956            }
7957        } catch (RemoteException e) {
7958            throw new SecurityException("Failed to verify package name ownership");
7959        }
7960
7961        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7962        synchronized (this) {
7963            if (incoming) {
7964                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7965                        callingUid);
7966                if (perms == null) {
7967                    Slog.w(TAG, "No permission grants found for " + packageName);
7968                } else {
7969                    for (UriPermission perm : perms.values()) {
7970                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7971                            result.add(perm.buildPersistedPublicApiObject());
7972                        }
7973                    }
7974                }
7975            } else {
7976                final int size = mGrantedUriPermissions.size();
7977                for (int i = 0; i < size; i++) {
7978                    final ArrayMap<GrantUri, UriPermission> perms =
7979                            mGrantedUriPermissions.valueAt(i);
7980                    for (UriPermission perm : perms.values()) {
7981                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7982                            result.add(perm.buildPersistedPublicApiObject());
7983                        }
7984                    }
7985                }
7986            }
7987        }
7988        return new ParceledListSlice<android.content.UriPermission>(result);
7989    }
7990
7991    @Override
7992    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7993        synchronized (this) {
7994            ProcessRecord app =
7995                who != null ? getRecordForAppLocked(who) : null;
7996            if (app == null) return;
7997
7998            Message msg = Message.obtain();
7999            msg.what = WAIT_FOR_DEBUGGER_MSG;
8000            msg.obj = app;
8001            msg.arg1 = waiting ? 1 : 0;
8002            mHandler.sendMessage(msg);
8003        }
8004    }
8005
8006    @Override
8007    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8008        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8009        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8010        outInfo.availMem = Process.getFreeMemory();
8011        outInfo.totalMem = Process.getTotalMemory();
8012        outInfo.threshold = homeAppMem;
8013        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8014        outInfo.hiddenAppThreshold = cachedAppMem;
8015        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8016                ProcessList.SERVICE_ADJ);
8017        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8018                ProcessList.VISIBLE_APP_ADJ);
8019        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8020                ProcessList.FOREGROUND_APP_ADJ);
8021    }
8022
8023    // =========================================================
8024    // TASK MANAGEMENT
8025    // =========================================================
8026
8027    @Override
8028    public List<IAppTask> getAppTasks(String callingPackage) {
8029        int callingUid = Binder.getCallingUid();
8030        long ident = Binder.clearCallingIdentity();
8031
8032        synchronized(this) {
8033            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8034            try {
8035                if (localLOGV) Slog.v(TAG, "getAppTasks");
8036
8037                final int N = mRecentTasks.size();
8038                for (int i = 0; i < N; i++) {
8039                    TaskRecord tr = mRecentTasks.get(i);
8040                    // Skip tasks that do not match the caller.  We don't need to verify
8041                    // callingPackage, because we are also limiting to callingUid and know
8042                    // that will limit to the correct security sandbox.
8043                    if (tr.effectiveUid != callingUid) {
8044                        continue;
8045                    }
8046                    Intent intent = tr.getBaseIntent();
8047                    if (intent == null ||
8048                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8049                        continue;
8050                    }
8051                    ActivityManager.RecentTaskInfo taskInfo =
8052                            createRecentTaskInfoFromTaskRecord(tr);
8053                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8054                    list.add(taskImpl);
8055                }
8056            } finally {
8057                Binder.restoreCallingIdentity(ident);
8058            }
8059            return list;
8060        }
8061    }
8062
8063    @Override
8064    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8065        final int callingUid = Binder.getCallingUid();
8066        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8067
8068        synchronized(this) {
8069            if (localLOGV) Slog.v(
8070                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8071
8072            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8073                    callingUid);
8074
8075            // TODO: Improve with MRU list from all ActivityStacks.
8076            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8077        }
8078
8079        return list;
8080    }
8081
8082    /**
8083     * Creates a new RecentTaskInfo from a TaskRecord.
8084     */
8085    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8086        // Update the task description to reflect any changes in the task stack
8087        tr.updateTaskDescription();
8088
8089        // Compose the recent task info
8090        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8091        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8092        rti.persistentId = tr.taskId;
8093        rti.baseIntent = new Intent(tr.getBaseIntent());
8094        rti.origActivity = tr.origActivity;
8095        rti.description = tr.lastDescription;
8096        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8097        rti.userId = tr.userId;
8098        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8099        rti.firstActiveTime = tr.firstActiveTime;
8100        rti.lastActiveTime = tr.lastActiveTime;
8101        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8102        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8103        return rti;
8104    }
8105
8106    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8107        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8108                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8109        if (!allowed) {
8110            if (checkPermission(android.Manifest.permission.GET_TASKS,
8111                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8112                // Temporary compatibility: some existing apps on the system image may
8113                // still be requesting the old permission and not switched to the new
8114                // one; if so, we'll still allow them full access.  This means we need
8115                // to see if they are holding the old permission and are a system app.
8116                try {
8117                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8118                        allowed = true;
8119                        Slog.w(TAG, caller + ": caller " + callingUid
8120                                + " is using old GET_TASKS but privileged; allowing");
8121                    }
8122                } catch (RemoteException e) {
8123                }
8124            }
8125        }
8126        if (!allowed) {
8127            Slog.w(TAG, caller + ": caller " + callingUid
8128                    + " does not hold GET_TASKS; limiting output");
8129        }
8130        return allowed;
8131    }
8132
8133    @Override
8134    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8135        final int callingUid = Binder.getCallingUid();
8136        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8137                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8138
8139        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8140        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8141        synchronized (this) {
8142            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8143                    callingUid);
8144            final boolean detailed = checkCallingPermission(
8145                    android.Manifest.permission.GET_DETAILED_TASKS)
8146                    == PackageManager.PERMISSION_GRANTED;
8147
8148            final int N = mRecentTasks.size();
8149            ArrayList<ActivityManager.RecentTaskInfo> res
8150                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8151                            maxNum < N ? maxNum : N);
8152
8153            final Set<Integer> includedUsers;
8154            if (includeProfiles) {
8155                includedUsers = getProfileIdsLocked(userId);
8156            } else {
8157                includedUsers = new HashSet<Integer>();
8158            }
8159            includedUsers.add(Integer.valueOf(userId));
8160
8161            for (int i=0; i<N && maxNum > 0; i++) {
8162                TaskRecord tr = mRecentTasks.get(i);
8163                // Only add calling user or related users recent tasks
8164                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8165                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8166                    continue;
8167                }
8168
8169                // Return the entry if desired by the caller.  We always return
8170                // the first entry, because callers always expect this to be the
8171                // foreground app.  We may filter others if the caller has
8172                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8173                // we should exclude the entry.
8174
8175                if (i == 0
8176                        || withExcluded
8177                        || (tr.intent == null)
8178                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8179                                == 0)) {
8180                    if (!allowed) {
8181                        // If the caller doesn't have the GET_TASKS permission, then only
8182                        // allow them to see a small subset of tasks -- their own and home.
8183                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8184                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8185                            continue;
8186                        }
8187                    }
8188                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8189                        if (tr.stack != null && tr.stack.isHomeStack()) {
8190                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8191                            continue;
8192                        }
8193                    }
8194                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8195                        // Don't include auto remove tasks that are finished or finishing.
8196                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8197                                + tr);
8198                        continue;
8199                    }
8200                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8201                            && !tr.isAvailable) {
8202                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8203                        continue;
8204                    }
8205
8206                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8207                    if (!detailed) {
8208                        rti.baseIntent.replaceExtras((Bundle)null);
8209                    }
8210
8211                    res.add(rti);
8212                    maxNum--;
8213                }
8214            }
8215            return res;
8216        }
8217    }
8218
8219    TaskRecord recentTaskForIdLocked(int id) {
8220        final int N = mRecentTasks.size();
8221            for (int i=0; i<N; i++) {
8222                TaskRecord tr = mRecentTasks.get(i);
8223                if (tr.taskId == id) {
8224                    return tr;
8225                }
8226            }
8227            return null;
8228    }
8229
8230    @Override
8231    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8232        synchronized (this) {
8233            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8234                    "getTaskThumbnail()");
8235            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8236            if (tr != null) {
8237                return tr.getTaskThumbnailLocked();
8238            }
8239        }
8240        return null;
8241    }
8242
8243    @Override
8244    public int addAppTask(IBinder activityToken, Intent intent,
8245            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8246        final int callingUid = Binder.getCallingUid();
8247        final long callingIdent = Binder.clearCallingIdentity();
8248
8249        try {
8250            synchronized (this) {
8251                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8252                if (r == null) {
8253                    throw new IllegalArgumentException("Activity does not exist; token="
8254                            + activityToken);
8255                }
8256                ComponentName comp = intent.getComponent();
8257                if (comp == null) {
8258                    throw new IllegalArgumentException("Intent " + intent
8259                            + " must specify explicit component");
8260                }
8261                if (thumbnail.getWidth() != mThumbnailWidth
8262                        || thumbnail.getHeight() != mThumbnailHeight) {
8263                    throw new IllegalArgumentException("Bad thumbnail size: got "
8264                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8265                            + mThumbnailWidth + "x" + mThumbnailHeight);
8266                }
8267                if (intent.getSelector() != null) {
8268                    intent.setSelector(null);
8269                }
8270                if (intent.getSourceBounds() != null) {
8271                    intent.setSourceBounds(null);
8272                }
8273                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8274                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8275                        // The caller has added this as an auto-remove task...  that makes no
8276                        // sense, so turn off auto-remove.
8277                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8278                    }
8279                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8280                    // Must be a new task.
8281                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8282                }
8283                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8284                    mLastAddedTaskActivity = null;
8285                }
8286                ActivityInfo ainfo = mLastAddedTaskActivity;
8287                if (ainfo == null) {
8288                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8289                            comp, 0, UserHandle.getUserId(callingUid));
8290                    if (ainfo.applicationInfo.uid != callingUid) {
8291                        throw new SecurityException(
8292                                "Can't add task for another application: target uid="
8293                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8294                    }
8295                }
8296
8297                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8298                        intent, description);
8299
8300                int trimIdx = trimRecentsForTaskLocked(task, false);
8301                if (trimIdx >= 0) {
8302                    // If this would have caused a trim, then we'll abort because that
8303                    // means it would be added at the end of the list but then just removed.
8304                    return INVALID_TASK_ID;
8305                }
8306
8307                final int N = mRecentTasks.size();
8308                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8309                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8310                    tr.removedFromRecents();
8311                }
8312
8313                task.inRecents = true;
8314                mRecentTasks.add(task);
8315                r.task.stack.addTask(task, false, false);
8316
8317                task.setLastThumbnail(thumbnail);
8318                task.freeLastThumbnail();
8319
8320                return task.taskId;
8321            }
8322        } finally {
8323            Binder.restoreCallingIdentity(callingIdent);
8324        }
8325    }
8326
8327    @Override
8328    public Point getAppTaskThumbnailSize() {
8329        synchronized (this) {
8330            return new Point(mThumbnailWidth,  mThumbnailHeight);
8331        }
8332    }
8333
8334    @Override
8335    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8336        synchronized (this) {
8337            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8338            if (r != null) {
8339                r.setTaskDescription(td);
8340                r.task.updateTaskDescription();
8341            }
8342        }
8343    }
8344
8345    @Override
8346    public Bitmap getTaskDescriptionIcon(String filename) {
8347        if (!FileUtils.isValidExtFilename(filename)
8348                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8349            throw new IllegalArgumentException("Bad filename: " + filename);
8350        }
8351        return mTaskPersister.getTaskDescriptionIcon(filename);
8352    }
8353
8354    @Override
8355    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8356            throws RemoteException {
8357        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8358                opts.getCustomInPlaceResId() == 0) {
8359            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8360                    "with valid animation");
8361        }
8362        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8363        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8364                opts.getCustomInPlaceResId());
8365        mWindowManager.executeAppTransition();
8366    }
8367
8368    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8369        mRecentTasks.remove(tr);
8370        tr.removedFromRecents();
8371        ComponentName component = tr.getBaseIntent().getComponent();
8372        if (component == null) {
8373            Slog.w(TAG, "No component for base intent of task: " + tr);
8374            return;
8375        }
8376
8377        if (!killProcess) {
8378            return;
8379        }
8380
8381        // Determine if the process(es) for this task should be killed.
8382        final String pkg = component.getPackageName();
8383        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8384        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8385        for (int i = 0; i < pmap.size(); i++) {
8386
8387            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8388            for (int j = 0; j < uids.size(); j++) {
8389                ProcessRecord proc = uids.valueAt(j);
8390                if (proc.userId != tr.userId) {
8391                    // Don't kill process for a different user.
8392                    continue;
8393                }
8394                if (proc == mHomeProcess) {
8395                    // Don't kill the home process along with tasks from the same package.
8396                    continue;
8397                }
8398                if (!proc.pkgList.containsKey(pkg)) {
8399                    // Don't kill process that is not associated with this task.
8400                    continue;
8401                }
8402
8403                for (int k = 0; k < proc.activities.size(); k++) {
8404                    TaskRecord otherTask = proc.activities.get(k).task;
8405                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8406                        // Don't kill process(es) that has an activity in a different task that is
8407                        // also in recents.
8408                        return;
8409                    }
8410                }
8411
8412                // Add process to kill list.
8413                procsToKill.add(proc);
8414            }
8415        }
8416
8417        // Find any running services associated with this app and stop if needed.
8418        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8419
8420        // Kill the running processes.
8421        for (int i = 0; i < procsToKill.size(); i++) {
8422            ProcessRecord pr = procsToKill.get(i);
8423            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8424                pr.kill("remove task", true);
8425            } else {
8426                pr.waitingToKill = "remove task";
8427            }
8428        }
8429    }
8430
8431    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8432        // Remove all tasks with activities in the specified package from the list of recent tasks
8433        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8434            TaskRecord tr = mRecentTasks.get(i);
8435            if (tr.userId != userId) continue;
8436
8437            ComponentName cn = tr.intent.getComponent();
8438            if (cn != null && cn.getPackageName().equals(packageName)) {
8439                // If the package name matches, remove the task.
8440                removeTaskByIdLocked(tr.taskId, true);
8441            }
8442        }
8443    }
8444
8445    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8446        final IPackageManager pm = AppGlobals.getPackageManager();
8447        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8448
8449        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8450            TaskRecord tr = mRecentTasks.get(i);
8451            if (tr.userId != userId) continue;
8452
8453            ComponentName cn = tr.intent.getComponent();
8454            if (cn != null && cn.getPackageName().equals(packageName)) {
8455                // Skip if component still exists in the package.
8456                if (componentsKnownToExist.contains(cn)) continue;
8457
8458                try {
8459                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8460                    if (info != null) {
8461                        componentsKnownToExist.add(cn);
8462                    } else {
8463                        removeTaskByIdLocked(tr.taskId, false);
8464                    }
8465                } catch (RemoteException e) {
8466                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8467                }
8468            }
8469        }
8470    }
8471
8472    /**
8473     * Removes the task with the specified task id.
8474     *
8475     * @param taskId Identifier of the task to be removed.
8476     * @param killProcess Kill any process associated with the task if possible.
8477     * @return Returns true if the given task was found and removed.
8478     */
8479    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8480        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8481        if (tr != null) {
8482            tr.removeTaskActivitiesLocked();
8483            cleanUpRemovedTaskLocked(tr, killProcess);
8484            if (tr.isPersistable) {
8485                notifyTaskPersisterLocked(null, true);
8486            }
8487            return true;
8488        }
8489        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8490        return false;
8491    }
8492
8493    @Override
8494    public boolean removeTask(int taskId) {
8495        synchronized (this) {
8496            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8497                    "removeTask()");
8498            long ident = Binder.clearCallingIdentity();
8499            try {
8500                return removeTaskByIdLocked(taskId, true);
8501            } finally {
8502                Binder.restoreCallingIdentity(ident);
8503            }
8504        }
8505    }
8506
8507    /**
8508     * TODO: Add mController hook
8509     */
8510    @Override
8511    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8512        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8513                "moveTaskToFront()");
8514
8515        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8516        synchronized(this) {
8517            moveTaskToFrontLocked(taskId, flags, options);
8518        }
8519    }
8520
8521    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8522        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8523                Binder.getCallingUid(), -1, -1, "Task to front")) {
8524            ActivityOptions.abort(options);
8525            return;
8526        }
8527        final long origId = Binder.clearCallingIdentity();
8528        try {
8529            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8530            if (task == null) {
8531                Slog.d(TAG, "Could not find task for id: "+ taskId);
8532                return;
8533            }
8534            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8535                mStackSupervisor.showLockTaskToast();
8536                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8537                return;
8538            }
8539            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8540            if (prev != null && prev.isRecentsActivity()) {
8541                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8542            }
8543            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8544        } finally {
8545            Binder.restoreCallingIdentity(origId);
8546        }
8547        ActivityOptions.abort(options);
8548    }
8549
8550    @Override
8551    public void moveTaskToBack(int taskId) {
8552        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8553                "moveTaskToBack()");
8554
8555        synchronized(this) {
8556            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8557            if (tr != null) {
8558                if (tr == mStackSupervisor.mLockTaskModeTask) {
8559                    mStackSupervisor.showLockTaskToast();
8560                    return;
8561                }
8562                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8563                ActivityStack stack = tr.stack;
8564                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8565                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8566                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8567                        return;
8568                    }
8569                }
8570                final long origId = Binder.clearCallingIdentity();
8571                try {
8572                    stack.moveTaskToBackLocked(taskId, null);
8573                } finally {
8574                    Binder.restoreCallingIdentity(origId);
8575                }
8576            }
8577        }
8578    }
8579
8580    /**
8581     * Moves an activity, and all of the other activities within the same task, to the bottom
8582     * of the history stack.  The activity's order within the task is unchanged.
8583     *
8584     * @param token A reference to the activity we wish to move
8585     * @param nonRoot If false then this only works if the activity is the root
8586     *                of a task; if true it will work for any activity in a task.
8587     * @return Returns true if the move completed, false if not.
8588     */
8589    @Override
8590    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8591        enforceNotIsolatedCaller("moveActivityTaskToBack");
8592        synchronized(this) {
8593            final long origId = Binder.clearCallingIdentity();
8594            try {
8595                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8596                if (taskId >= 0) {
8597                    if ((mStackSupervisor.mLockTaskModeTask != null)
8598                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8599                        mStackSupervisor.showLockTaskToast();
8600                        return false;
8601                    }
8602                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8603                }
8604            } finally {
8605                Binder.restoreCallingIdentity(origId);
8606            }
8607        }
8608        return false;
8609    }
8610
8611    @Override
8612    public void moveTaskBackwards(int task) {
8613        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8614                "moveTaskBackwards()");
8615
8616        synchronized(this) {
8617            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8618                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8619                return;
8620            }
8621            final long origId = Binder.clearCallingIdentity();
8622            moveTaskBackwardsLocked(task);
8623            Binder.restoreCallingIdentity(origId);
8624        }
8625    }
8626
8627    private final void moveTaskBackwardsLocked(int task) {
8628        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8629    }
8630
8631    @Override
8632    public IBinder getHomeActivityToken() throws RemoteException {
8633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8634                "getHomeActivityToken()");
8635        synchronized (this) {
8636            return mStackSupervisor.getHomeActivityToken();
8637        }
8638    }
8639
8640    @Override
8641    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8642            IActivityContainerCallback callback) throws RemoteException {
8643        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8644                "createActivityContainer()");
8645        synchronized (this) {
8646            if (parentActivityToken == null) {
8647                throw new IllegalArgumentException("parent token must not be null");
8648            }
8649            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8650            if (r == null) {
8651                return null;
8652            }
8653            if (callback == null) {
8654                throw new IllegalArgumentException("callback must not be null");
8655            }
8656            return mStackSupervisor.createActivityContainer(r, callback);
8657        }
8658    }
8659
8660    @Override
8661    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8662        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8663                "deleteActivityContainer()");
8664        synchronized (this) {
8665            mStackSupervisor.deleteActivityContainer(container);
8666        }
8667    }
8668
8669    @Override
8670    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8671            throws RemoteException {
8672        synchronized (this) {
8673            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8674            if (stack != null) {
8675                return stack.mActivityContainer;
8676            }
8677            return null;
8678        }
8679    }
8680
8681    @Override
8682    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8683        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8684                "moveTaskToStack()");
8685        if (stackId == HOME_STACK_ID) {
8686            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8687                    new RuntimeException("here").fillInStackTrace());
8688        }
8689        synchronized (this) {
8690            long ident = Binder.clearCallingIdentity();
8691            try {
8692                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8693                        + stackId + " toTop=" + toTop);
8694                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8695            } finally {
8696                Binder.restoreCallingIdentity(ident);
8697            }
8698        }
8699    }
8700
8701    @Override
8702    public void resizeStack(int stackBoxId, Rect bounds) {
8703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8704                "resizeStackBox()");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            mWindowManager.resizeStack(stackBoxId, bounds);
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public List<StackInfo> getAllStackInfos() {
8715        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8716                "getAllStackInfos()");
8717        long ident = Binder.clearCallingIdentity();
8718        try {
8719            synchronized (this) {
8720                return mStackSupervisor.getAllStackInfosLocked();
8721            }
8722        } finally {
8723            Binder.restoreCallingIdentity(ident);
8724        }
8725    }
8726
8727    @Override
8728    public StackInfo getStackInfo(int stackId) {
8729        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8730                "getStackInfo()");
8731        long ident = Binder.clearCallingIdentity();
8732        try {
8733            synchronized (this) {
8734                return mStackSupervisor.getStackInfoLocked(stackId);
8735            }
8736        } finally {
8737            Binder.restoreCallingIdentity(ident);
8738        }
8739    }
8740
8741    @Override
8742    public boolean isInHomeStack(int taskId) {
8743        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                "getStackInfo()");
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            synchronized (this) {
8748                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8749                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8750            }
8751        } finally {
8752            Binder.restoreCallingIdentity(ident);
8753        }
8754    }
8755
8756    @Override
8757    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8758        synchronized(this) {
8759            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8760        }
8761    }
8762
8763    private boolean isLockTaskAuthorized(String pkg) {
8764        final DevicePolicyManager dpm = (DevicePolicyManager)
8765                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8766        try {
8767            int uid = mContext.getPackageManager().getPackageUid(pkg,
8768                    Binder.getCallingUserHandle().getIdentifier());
8769            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8770        } catch (NameNotFoundException e) {
8771            return false;
8772        }
8773    }
8774
8775    void startLockTaskMode(TaskRecord task) {
8776        final String pkg;
8777        synchronized (this) {
8778            pkg = task.intent.getComponent().getPackageName();
8779        }
8780        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8781        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8782            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8783                    StatusBarManagerInternal.class);
8784            if (statusBarManager != null) {
8785                statusBarManager.showScreenPinningRequest();
8786            }
8787            return;
8788        }
8789        long ident = Binder.clearCallingIdentity();
8790        try {
8791            synchronized (this) {
8792                // Since we lost lock on task, make sure it is still there.
8793                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8794                if (task != null) {
8795                    if (!isSystemInitiated
8796                            && ((mStackSupervisor.getFocusedStack() == null)
8797                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8798                        throw new IllegalArgumentException("Invalid task, not in foreground");
8799                    }
8800                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8801                }
8802            }
8803        } finally {
8804            Binder.restoreCallingIdentity(ident);
8805        }
8806    }
8807
8808    @Override
8809    public void startLockTaskMode(int taskId) {
8810        final TaskRecord task;
8811        long ident = Binder.clearCallingIdentity();
8812        try {
8813            synchronized (this) {
8814                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8815            }
8816        } finally {
8817            Binder.restoreCallingIdentity(ident);
8818        }
8819        if (task != null) {
8820            startLockTaskMode(task);
8821        }
8822    }
8823
8824    @Override
8825    public void startLockTaskMode(IBinder token) {
8826        final TaskRecord task;
8827        long ident = Binder.clearCallingIdentity();
8828        try {
8829            synchronized (this) {
8830                final ActivityRecord r = ActivityRecord.forToken(token);
8831                if (r == null) {
8832                    return;
8833                }
8834                task = r.task;
8835            }
8836        } finally {
8837            Binder.restoreCallingIdentity(ident);
8838        }
8839        if (task != null) {
8840            startLockTaskMode(task);
8841        }
8842    }
8843
8844    @Override
8845    public void startLockTaskModeOnCurrent() throws RemoteException {
8846        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8847                "startLockTaskModeOnCurrent");
8848        long ident = Binder.clearCallingIdentity();
8849        try {
8850            ActivityRecord r = null;
8851            synchronized (this) {
8852                r = mStackSupervisor.topRunningActivityLocked();
8853            }
8854            startLockTaskMode(r.task);
8855        } finally {
8856            Binder.restoreCallingIdentity(ident);
8857        }
8858    }
8859
8860    @Override
8861    public void stopLockTaskMode() {
8862        // Verify that the user matches the package of the intent for the TaskRecord
8863        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8864        // and stopLockTaskMode.
8865        final int callingUid = Binder.getCallingUid();
8866        if (callingUid != Process.SYSTEM_UID) {
8867            try {
8868                String pkg =
8869                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8870                int uid = mContext.getPackageManager().getPackageUid(pkg,
8871                        Binder.getCallingUserHandle().getIdentifier());
8872                if (uid != callingUid) {
8873                    throw new SecurityException("Invalid uid, expected " + uid);
8874                }
8875            } catch (NameNotFoundException e) {
8876                Log.d(TAG, "stopLockTaskMode " + e);
8877                return;
8878            }
8879        }
8880        long ident = Binder.clearCallingIdentity();
8881        try {
8882            Log.d(TAG, "stopLockTaskMode");
8883            // Stop lock task
8884            synchronized (this) {
8885                mStackSupervisor.setLockTaskModeLocked(null, false);
8886            }
8887        } finally {
8888            Binder.restoreCallingIdentity(ident);
8889        }
8890    }
8891
8892    @Override
8893    public void stopLockTaskModeOnCurrent() throws RemoteException {
8894        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8895                "stopLockTaskModeOnCurrent");
8896        long ident = Binder.clearCallingIdentity();
8897        try {
8898            stopLockTaskMode();
8899        } finally {
8900            Binder.restoreCallingIdentity(ident);
8901        }
8902    }
8903
8904    @Override
8905    public boolean isInLockTaskMode() {
8906        synchronized (this) {
8907            return mStackSupervisor.isInLockTaskMode();
8908        }
8909    }
8910
8911    // =========================================================
8912    // CONTENT PROVIDERS
8913    // =========================================================
8914
8915    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8916        List<ProviderInfo> providers = null;
8917        try {
8918            providers = AppGlobals.getPackageManager().
8919                queryContentProviders(app.processName, app.uid,
8920                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8921        } catch (RemoteException ex) {
8922        }
8923        if (DEBUG_MU)
8924            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8925        int userId = app.userId;
8926        if (providers != null) {
8927            int N = providers.size();
8928            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8929            for (int i=0; i<N; i++) {
8930                ProviderInfo cpi =
8931                    (ProviderInfo)providers.get(i);
8932                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8933                        cpi.name, cpi.flags);
8934                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8935                    // This is a singleton provider, but a user besides the
8936                    // default user is asking to initialize a process it runs
8937                    // in...  well, no, it doesn't actually run in this process,
8938                    // it runs in the process of the default user.  Get rid of it.
8939                    providers.remove(i);
8940                    N--;
8941                    i--;
8942                    continue;
8943                }
8944
8945                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8946                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8947                if (cpr == null) {
8948                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8949                    mProviderMap.putProviderByClass(comp, cpr);
8950                }
8951                if (DEBUG_MU)
8952                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8953                app.pubProviders.put(cpi.name, cpr);
8954                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8955                    // Don't add this if it is a platform component that is marked
8956                    // to run in multiple processes, because this is actually
8957                    // part of the framework so doesn't make sense to track as a
8958                    // separate apk in the process.
8959                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8960                            mProcessStats);
8961                }
8962                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8963            }
8964        }
8965        return providers;
8966    }
8967
8968    /**
8969     * Check if {@link ProcessRecord} has a possible chance at accessing the
8970     * given {@link ProviderInfo}. Final permission checking is always done
8971     * in {@link ContentProvider}.
8972     */
8973    private final String checkContentProviderPermissionLocked(
8974            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8975        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8976        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8977        boolean checkedGrants = false;
8978        if (checkUser) {
8979            // Looking for cross-user grants before enforcing the typical cross-users permissions
8980            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8981            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8982                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8983                    return null;
8984                }
8985                checkedGrants = true;
8986            }
8987            userId = handleIncomingUser(callingPid, callingUid, userId,
8988                    false, ALLOW_NON_FULL,
8989                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8990            if (userId != tmpTargetUserId) {
8991                // When we actually went to determine the final targer user ID, this ended
8992                // up different than our initial check for the authority.  This is because
8993                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8994                // SELF.  So we need to re-check the grants again.
8995                checkedGrants = false;
8996            }
8997        }
8998        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8999                cpi.applicationInfo.uid, cpi.exported)
9000                == PackageManager.PERMISSION_GRANTED) {
9001            return null;
9002        }
9003        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9004                cpi.applicationInfo.uid, cpi.exported)
9005                == PackageManager.PERMISSION_GRANTED) {
9006            return null;
9007        }
9008
9009        PathPermission[] pps = cpi.pathPermissions;
9010        if (pps != null) {
9011            int i = pps.length;
9012            while (i > 0) {
9013                i--;
9014                PathPermission pp = pps[i];
9015                String pprperm = pp.getReadPermission();
9016                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9017                        cpi.applicationInfo.uid, cpi.exported)
9018                        == PackageManager.PERMISSION_GRANTED) {
9019                    return null;
9020                }
9021                String ppwperm = pp.getWritePermission();
9022                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9023                        cpi.applicationInfo.uid, cpi.exported)
9024                        == PackageManager.PERMISSION_GRANTED) {
9025                    return null;
9026                }
9027            }
9028        }
9029        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9030            return null;
9031        }
9032
9033        String msg;
9034        if (!cpi.exported) {
9035            msg = "Permission Denial: opening provider " + cpi.name
9036                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9037                    + ", uid=" + callingUid + ") that is not exported from uid "
9038                    + cpi.applicationInfo.uid;
9039        } else {
9040            msg = "Permission Denial: opening provider " + cpi.name
9041                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9042                    + ", uid=" + callingUid + ") requires "
9043                    + cpi.readPermission + " or " + cpi.writePermission;
9044        }
9045        Slog.w(TAG, msg);
9046        return msg;
9047    }
9048
9049    /**
9050     * Returns if the ContentProvider has granted a uri to callingUid
9051     */
9052    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9053        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9054        if (perms != null) {
9055            for (int i=perms.size()-1; i>=0; i--) {
9056                GrantUri grantUri = perms.keyAt(i);
9057                if (grantUri.sourceUserId == userId || !checkUser) {
9058                    if (matchesProvider(grantUri.uri, cpi)) {
9059                        return true;
9060                    }
9061                }
9062            }
9063        }
9064        return false;
9065    }
9066
9067    /**
9068     * Returns true if the uri authority is one of the authorities specified in the provider.
9069     */
9070    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9071        String uriAuth = uri.getAuthority();
9072        String cpiAuth = cpi.authority;
9073        if (cpiAuth.indexOf(';') == -1) {
9074            return cpiAuth.equals(uriAuth);
9075        }
9076        String[] cpiAuths = cpiAuth.split(";");
9077        int length = cpiAuths.length;
9078        for (int i = 0; i < length; i++) {
9079            if (cpiAuths[i].equals(uriAuth)) return true;
9080        }
9081        return false;
9082    }
9083
9084    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9085            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9086        if (r != null) {
9087            for (int i=0; i<r.conProviders.size(); i++) {
9088                ContentProviderConnection conn = r.conProviders.get(i);
9089                if (conn.provider == cpr) {
9090                    if (DEBUG_PROVIDER) Slog.v(TAG,
9091                            "Adding provider requested by "
9092                            + r.processName + " from process "
9093                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9094                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9095                    if (stable) {
9096                        conn.stableCount++;
9097                        conn.numStableIncs++;
9098                    } else {
9099                        conn.unstableCount++;
9100                        conn.numUnstableIncs++;
9101                    }
9102                    return conn;
9103                }
9104            }
9105            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9106            if (stable) {
9107                conn.stableCount = 1;
9108                conn.numStableIncs = 1;
9109            } else {
9110                conn.unstableCount = 1;
9111                conn.numUnstableIncs = 1;
9112            }
9113            cpr.connections.add(conn);
9114            r.conProviders.add(conn);
9115            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9116            return conn;
9117        }
9118        cpr.addExternalProcessHandleLocked(externalProcessToken);
9119        return null;
9120    }
9121
9122    boolean decProviderCountLocked(ContentProviderConnection conn,
9123            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9124        if (conn != null) {
9125            cpr = conn.provider;
9126            if (DEBUG_PROVIDER) Slog.v(TAG,
9127                    "Removing provider requested by "
9128                    + conn.client.processName + " from process "
9129                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9130                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9131            if (stable) {
9132                conn.stableCount--;
9133            } else {
9134                conn.unstableCount--;
9135            }
9136            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9137                cpr.connections.remove(conn);
9138                conn.client.conProviders.remove(conn);
9139                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9140                return true;
9141            }
9142            return false;
9143        }
9144        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9145        return false;
9146    }
9147
9148    private void checkTime(long startTime, String where) {
9149        long now = SystemClock.elapsedRealtime();
9150        if ((now-startTime) > 1000) {
9151            // If we are taking more than a second, log about it.
9152            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9153        }
9154    }
9155
9156    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9157            String name, IBinder token, boolean stable, int userId) {
9158        ContentProviderRecord cpr;
9159        ContentProviderConnection conn = null;
9160        ProviderInfo cpi = null;
9161
9162        synchronized(this) {
9163            long startTime = SystemClock.elapsedRealtime();
9164
9165            ProcessRecord r = null;
9166            if (caller != null) {
9167                r = getRecordForAppLocked(caller);
9168                if (r == null) {
9169                    throw new SecurityException(
9170                            "Unable to find app for caller " + caller
9171                          + " (pid=" + Binder.getCallingPid()
9172                          + ") when getting content provider " + name);
9173                }
9174            }
9175
9176            boolean checkCrossUser = true;
9177
9178            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9179
9180            // First check if this content provider has been published...
9181            cpr = mProviderMap.getProviderByName(name, userId);
9182            // If that didn't work, check if it exists for user 0 and then
9183            // verify that it's a singleton provider before using it.
9184            if (cpr == null && userId != UserHandle.USER_OWNER) {
9185                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9186                if (cpr != null) {
9187                    cpi = cpr.info;
9188                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9189                            cpi.name, cpi.flags)
9190                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9191                        userId = UserHandle.USER_OWNER;
9192                        checkCrossUser = false;
9193                    } else {
9194                        cpr = null;
9195                        cpi = null;
9196                    }
9197                }
9198            }
9199
9200            boolean providerRunning = cpr != null;
9201            if (providerRunning) {
9202                cpi = cpr.info;
9203                String msg;
9204                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9205                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9206                        != null) {
9207                    throw new SecurityException(msg);
9208                }
9209                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9210
9211                if (r != null && cpr.canRunHere(r)) {
9212                    // This provider has been published or is in the process
9213                    // of being published...  but it is also allowed to run
9214                    // in the caller's process, so don't make a connection
9215                    // and just let the caller instantiate its own instance.
9216                    ContentProviderHolder holder = cpr.newHolder(null);
9217                    // don't give caller the provider object, it needs
9218                    // to make its own.
9219                    holder.provider = null;
9220                    return holder;
9221                }
9222
9223                final long origId = Binder.clearCallingIdentity();
9224
9225                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9226
9227                // In this case the provider instance already exists, so we can
9228                // return it right away.
9229                conn = incProviderCountLocked(r, cpr, token, stable);
9230                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9231                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9232                        // If this is a perceptible app accessing the provider,
9233                        // make sure to count it as being accessed and thus
9234                        // back up on the LRU list.  This is good because
9235                        // content providers are often expensive to start.
9236                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9237                        updateLruProcessLocked(cpr.proc, false, null);
9238                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9239                    }
9240                }
9241
9242                if (cpr.proc != null) {
9243                    if (false) {
9244                        if (cpr.name.flattenToShortString().equals(
9245                                "com.android.providers.calendar/.CalendarProvider2")) {
9246                            Slog.v(TAG, "****************** KILLING "
9247                                + cpr.name.flattenToShortString());
9248                            Process.killProcess(cpr.proc.pid);
9249                        }
9250                    }
9251                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9252                    boolean success = updateOomAdjLocked(cpr.proc);
9253                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9254                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9255                    // NOTE: there is still a race here where a signal could be
9256                    // pending on the process even though we managed to update its
9257                    // adj level.  Not sure what to do about this, but at least
9258                    // the race is now smaller.
9259                    if (!success) {
9260                        // Uh oh...  it looks like the provider's process
9261                        // has been killed on us.  We need to wait for a new
9262                        // process to be started, and make sure its death
9263                        // doesn't kill our process.
9264                        Slog.i(TAG,
9265                                "Existing provider " + cpr.name.flattenToShortString()
9266                                + " is crashing; detaching " + r);
9267                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9268                        checkTime(startTime, "getContentProviderImpl: before appDied");
9269                        appDiedLocked(cpr.proc);
9270                        checkTime(startTime, "getContentProviderImpl: after appDied");
9271                        if (!lastRef) {
9272                            // This wasn't the last ref our process had on
9273                            // the provider...  we have now been killed, bail.
9274                            return null;
9275                        }
9276                        providerRunning = false;
9277                        conn = null;
9278                    }
9279                }
9280
9281                Binder.restoreCallingIdentity(origId);
9282            }
9283
9284            boolean singleton;
9285            if (!providerRunning) {
9286                try {
9287                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9288                    cpi = AppGlobals.getPackageManager().
9289                        resolveContentProvider(name,
9290                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9291                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9292                } catch (RemoteException ex) {
9293                }
9294                if (cpi == null) {
9295                    return null;
9296                }
9297                // If the provider is a singleton AND
9298                // (it's a call within the same user || the provider is a
9299                // privileged app)
9300                // Then allow connecting to the singleton provider
9301                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9302                        cpi.name, cpi.flags)
9303                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9304                if (singleton) {
9305                    userId = UserHandle.USER_OWNER;
9306                }
9307                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9308                checkTime(startTime, "getContentProviderImpl: got app info for user");
9309
9310                String msg;
9311                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9312                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9313                        != null) {
9314                    throw new SecurityException(msg);
9315                }
9316                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9317
9318                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9319                        && !cpi.processName.equals("system")) {
9320                    // If this content provider does not run in the system
9321                    // process, and the system is not yet ready to run other
9322                    // processes, then fail fast instead of hanging.
9323                    throw new IllegalArgumentException(
9324                            "Attempt to launch content provider before system ready");
9325                }
9326
9327                // Make sure that the user who owns this provider is running.  If not,
9328                // we don't want to allow it to run.
9329                if (!isUserRunningLocked(userId, false)) {
9330                    Slog.w(TAG, "Unable to launch app "
9331                            + cpi.applicationInfo.packageName + "/"
9332                            + cpi.applicationInfo.uid + " for provider "
9333                            + name + ": user " + userId + " is stopped");
9334                    return null;
9335                }
9336
9337                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9338                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9339                cpr = mProviderMap.getProviderByClass(comp, userId);
9340                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9341                final boolean firstClass = cpr == null;
9342                if (firstClass) {
9343                    final long ident = Binder.clearCallingIdentity();
9344                    try {
9345                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9346                        ApplicationInfo ai =
9347                            AppGlobals.getPackageManager().
9348                                getApplicationInfo(
9349                                        cpi.applicationInfo.packageName,
9350                                        STOCK_PM_FLAGS, userId);
9351                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9352                        if (ai == null) {
9353                            Slog.w(TAG, "No package info for content provider "
9354                                    + cpi.name);
9355                            return null;
9356                        }
9357                        ai = getAppInfoForUser(ai, userId);
9358                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9359                    } catch (RemoteException ex) {
9360                        // pm is in same process, this will never happen.
9361                    } finally {
9362                        Binder.restoreCallingIdentity(ident);
9363                    }
9364                }
9365
9366                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9367
9368                if (r != null && cpr.canRunHere(r)) {
9369                    // If this is a multiprocess provider, then just return its
9370                    // info and allow the caller to instantiate it.  Only do
9371                    // this if the provider is the same user as the caller's
9372                    // process, or can run as root (so can be in any process).
9373                    return cpr.newHolder(null);
9374                }
9375
9376                if (DEBUG_PROVIDER) {
9377                    RuntimeException e = new RuntimeException("here");
9378                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9379                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9380                }
9381
9382                // This is single process, and our app is now connecting to it.
9383                // See if we are already in the process of launching this
9384                // provider.
9385                final int N = mLaunchingProviders.size();
9386                int i;
9387                for (i=0; i<N; i++) {
9388                    if (mLaunchingProviders.get(i) == cpr) {
9389                        break;
9390                    }
9391                }
9392
9393                // If the provider is not already being launched, then get it
9394                // started.
9395                if (i >= N) {
9396                    final long origId = Binder.clearCallingIdentity();
9397
9398                    try {
9399                        // Content provider is now in use, its package can't be stopped.
9400                        try {
9401                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9402                            AppGlobals.getPackageManager().setPackageStoppedState(
9403                                    cpr.appInfo.packageName, false, userId);
9404                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9405                        } catch (RemoteException e) {
9406                        } catch (IllegalArgumentException e) {
9407                            Slog.w(TAG, "Failed trying to unstop package "
9408                                    + cpr.appInfo.packageName + ": " + e);
9409                        }
9410
9411                        // Use existing process if already started
9412                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9413                        ProcessRecord proc = getProcessRecordLocked(
9414                                cpi.processName, cpr.appInfo.uid, false);
9415                        if (proc != null && proc.thread != null) {
9416                            if (DEBUG_PROVIDER) {
9417                                Slog.d(TAG, "Installing in existing process " + proc);
9418                            }
9419                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9420                            proc.pubProviders.put(cpi.name, cpr);
9421                            try {
9422                                proc.thread.scheduleInstallProvider(cpi);
9423                            } catch (RemoteException e) {
9424                            }
9425                        } else {
9426                            checkTime(startTime, "getContentProviderImpl: before start process");
9427                            proc = startProcessLocked(cpi.processName,
9428                                    cpr.appInfo, false, 0, "content provider",
9429                                    new ComponentName(cpi.applicationInfo.packageName,
9430                                            cpi.name), false, false, false);
9431                            checkTime(startTime, "getContentProviderImpl: after start process");
9432                            if (proc == null) {
9433                                Slog.w(TAG, "Unable to launch app "
9434                                        + cpi.applicationInfo.packageName + "/"
9435                                        + cpi.applicationInfo.uid + " for provider "
9436                                        + name + ": process is bad");
9437                                return null;
9438                            }
9439                        }
9440                        cpr.launchingApp = proc;
9441                        mLaunchingProviders.add(cpr);
9442                    } finally {
9443                        Binder.restoreCallingIdentity(origId);
9444                    }
9445                }
9446
9447                checkTime(startTime, "getContentProviderImpl: updating data structures");
9448
9449                // Make sure the provider is published (the same provider class
9450                // may be published under multiple names).
9451                if (firstClass) {
9452                    mProviderMap.putProviderByClass(comp, cpr);
9453                }
9454
9455                mProviderMap.putProviderByName(name, cpr);
9456                conn = incProviderCountLocked(r, cpr, token, stable);
9457                if (conn != null) {
9458                    conn.waiting = true;
9459                }
9460            }
9461            checkTime(startTime, "getContentProviderImpl: done!");
9462        }
9463
9464        // Wait for the provider to be published...
9465        synchronized (cpr) {
9466            while (cpr.provider == null) {
9467                if (cpr.launchingApp == null) {
9468                    Slog.w(TAG, "Unable to launch app "
9469                            + cpi.applicationInfo.packageName + "/"
9470                            + cpi.applicationInfo.uid + " for provider "
9471                            + name + ": launching app became null");
9472                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9473                            UserHandle.getUserId(cpi.applicationInfo.uid),
9474                            cpi.applicationInfo.packageName,
9475                            cpi.applicationInfo.uid, name);
9476                    return null;
9477                }
9478                try {
9479                    if (DEBUG_MU) {
9480                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9481                                + cpr.launchingApp);
9482                    }
9483                    if (conn != null) {
9484                        conn.waiting = true;
9485                    }
9486                    cpr.wait();
9487                } catch (InterruptedException ex) {
9488                } finally {
9489                    if (conn != null) {
9490                        conn.waiting = false;
9491                    }
9492                }
9493            }
9494        }
9495        return cpr != null ? cpr.newHolder(conn) : null;
9496    }
9497
9498    @Override
9499    public final ContentProviderHolder getContentProvider(
9500            IApplicationThread caller, String name, int userId, boolean stable) {
9501        enforceNotIsolatedCaller("getContentProvider");
9502        if (caller == null) {
9503            String msg = "null IApplicationThread when getting content provider "
9504                    + name;
9505            Slog.w(TAG, msg);
9506            throw new SecurityException(msg);
9507        }
9508        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9509        // with cross-user grant.
9510        return getContentProviderImpl(caller, name, null, stable, userId);
9511    }
9512
9513    public ContentProviderHolder getContentProviderExternal(
9514            String name, int userId, IBinder token) {
9515        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9516            "Do not have permission in call getContentProviderExternal()");
9517        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9518                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9519        return getContentProviderExternalUnchecked(name, token, userId);
9520    }
9521
9522    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9523            IBinder token, int userId) {
9524        return getContentProviderImpl(null, name, token, true, userId);
9525    }
9526
9527    /**
9528     * Drop a content provider from a ProcessRecord's bookkeeping
9529     */
9530    public void removeContentProvider(IBinder connection, boolean stable) {
9531        enforceNotIsolatedCaller("removeContentProvider");
9532        long ident = Binder.clearCallingIdentity();
9533        try {
9534            synchronized (this) {
9535                ContentProviderConnection conn;
9536                try {
9537                    conn = (ContentProviderConnection)connection;
9538                } catch (ClassCastException e) {
9539                    String msg ="removeContentProvider: " + connection
9540                            + " not a ContentProviderConnection";
9541                    Slog.w(TAG, msg);
9542                    throw new IllegalArgumentException(msg);
9543                }
9544                if (conn == null) {
9545                    throw new NullPointerException("connection is null");
9546                }
9547                if (decProviderCountLocked(conn, null, null, stable)) {
9548                    updateOomAdjLocked();
9549                }
9550            }
9551        } finally {
9552            Binder.restoreCallingIdentity(ident);
9553        }
9554    }
9555
9556    public void removeContentProviderExternal(String name, IBinder token) {
9557        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9558            "Do not have permission in call removeContentProviderExternal()");
9559        int userId = UserHandle.getCallingUserId();
9560        long ident = Binder.clearCallingIdentity();
9561        try {
9562            removeContentProviderExternalUnchecked(name, token, userId);
9563        } finally {
9564            Binder.restoreCallingIdentity(ident);
9565        }
9566    }
9567
9568    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9569        synchronized (this) {
9570            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9571            if(cpr == null) {
9572                //remove from mProvidersByClass
9573                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9574                return;
9575            }
9576
9577            //update content provider record entry info
9578            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9579            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9580            if (localCpr.hasExternalProcessHandles()) {
9581                if (localCpr.removeExternalProcessHandleLocked(token)) {
9582                    updateOomAdjLocked();
9583                } else {
9584                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9585                            + " with no external reference for token: "
9586                            + token + ".");
9587                }
9588            } else {
9589                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9590                        + " with no external references.");
9591            }
9592        }
9593    }
9594
9595    public final void publishContentProviders(IApplicationThread caller,
9596            List<ContentProviderHolder> providers) {
9597        if (providers == null) {
9598            return;
9599        }
9600
9601        enforceNotIsolatedCaller("publishContentProviders");
9602        synchronized (this) {
9603            final ProcessRecord r = getRecordForAppLocked(caller);
9604            if (DEBUG_MU)
9605                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9606            if (r == null) {
9607                throw new SecurityException(
9608                        "Unable to find app for caller " + caller
9609                      + " (pid=" + Binder.getCallingPid()
9610                      + ") when publishing content providers");
9611            }
9612
9613            final long origId = Binder.clearCallingIdentity();
9614
9615            final int N = providers.size();
9616            for (int i=0; i<N; i++) {
9617                ContentProviderHolder src = providers.get(i);
9618                if (src == null || src.info == null || src.provider == null) {
9619                    continue;
9620                }
9621                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9622                if (DEBUG_MU)
9623                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9624                if (dst != null) {
9625                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9626                    mProviderMap.putProviderByClass(comp, dst);
9627                    String names[] = dst.info.authority.split(";");
9628                    for (int j = 0; j < names.length; j++) {
9629                        mProviderMap.putProviderByName(names[j], dst);
9630                    }
9631
9632                    int NL = mLaunchingProviders.size();
9633                    int j;
9634                    for (j=0; j<NL; j++) {
9635                        if (mLaunchingProviders.get(j) == dst) {
9636                            mLaunchingProviders.remove(j);
9637                            j--;
9638                            NL--;
9639                        }
9640                    }
9641                    synchronized (dst) {
9642                        dst.provider = src.provider;
9643                        dst.proc = r;
9644                        dst.notifyAll();
9645                    }
9646                    updateOomAdjLocked(r);
9647                }
9648            }
9649
9650            Binder.restoreCallingIdentity(origId);
9651        }
9652    }
9653
9654    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9655        ContentProviderConnection conn;
9656        try {
9657            conn = (ContentProviderConnection)connection;
9658        } catch (ClassCastException e) {
9659            String msg ="refContentProvider: " + connection
9660                    + " not a ContentProviderConnection";
9661            Slog.w(TAG, msg);
9662            throw new IllegalArgumentException(msg);
9663        }
9664        if (conn == null) {
9665            throw new NullPointerException("connection is null");
9666        }
9667
9668        synchronized (this) {
9669            if (stable > 0) {
9670                conn.numStableIncs += stable;
9671            }
9672            stable = conn.stableCount + stable;
9673            if (stable < 0) {
9674                throw new IllegalStateException("stableCount < 0: " + stable);
9675            }
9676
9677            if (unstable > 0) {
9678                conn.numUnstableIncs += unstable;
9679            }
9680            unstable = conn.unstableCount + unstable;
9681            if (unstable < 0) {
9682                throw new IllegalStateException("unstableCount < 0: " + unstable);
9683            }
9684
9685            if ((stable+unstable) <= 0) {
9686                throw new IllegalStateException("ref counts can't go to zero here: stable="
9687                        + stable + " unstable=" + unstable);
9688            }
9689            conn.stableCount = stable;
9690            conn.unstableCount = unstable;
9691            return !conn.dead;
9692        }
9693    }
9694
9695    public void unstableProviderDied(IBinder connection) {
9696        ContentProviderConnection conn;
9697        try {
9698            conn = (ContentProviderConnection)connection;
9699        } catch (ClassCastException e) {
9700            String msg ="refContentProvider: " + connection
9701                    + " not a ContentProviderConnection";
9702            Slog.w(TAG, msg);
9703            throw new IllegalArgumentException(msg);
9704        }
9705        if (conn == null) {
9706            throw new NullPointerException("connection is null");
9707        }
9708
9709        // Safely retrieve the content provider associated with the connection.
9710        IContentProvider provider;
9711        synchronized (this) {
9712            provider = conn.provider.provider;
9713        }
9714
9715        if (provider == null) {
9716            // Um, yeah, we're way ahead of you.
9717            return;
9718        }
9719
9720        // Make sure the caller is being honest with us.
9721        if (provider.asBinder().pingBinder()) {
9722            // Er, no, still looks good to us.
9723            synchronized (this) {
9724                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9725                        + " says " + conn + " died, but we don't agree");
9726                return;
9727            }
9728        }
9729
9730        // Well look at that!  It's dead!
9731        synchronized (this) {
9732            if (conn.provider.provider != provider) {
9733                // But something changed...  good enough.
9734                return;
9735            }
9736
9737            ProcessRecord proc = conn.provider.proc;
9738            if (proc == null || proc.thread == null) {
9739                // Seems like the process is already cleaned up.
9740                return;
9741            }
9742
9743            // As far as we're concerned, this is just like receiving a
9744            // death notification...  just a bit prematurely.
9745            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9746                    + ") early provider death");
9747            final long ident = Binder.clearCallingIdentity();
9748            try {
9749                appDiedLocked(proc);
9750            } finally {
9751                Binder.restoreCallingIdentity(ident);
9752            }
9753        }
9754    }
9755
9756    @Override
9757    public void appNotRespondingViaProvider(IBinder connection) {
9758        enforceCallingPermission(
9759                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9760
9761        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9762        if (conn == null) {
9763            Slog.w(TAG, "ContentProviderConnection is null");
9764            return;
9765        }
9766
9767        final ProcessRecord host = conn.provider.proc;
9768        if (host == null) {
9769            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9770            return;
9771        }
9772
9773        final long token = Binder.clearCallingIdentity();
9774        try {
9775            appNotResponding(host, null, null, false, "ContentProvider not responding");
9776        } finally {
9777            Binder.restoreCallingIdentity(token);
9778        }
9779    }
9780
9781    public final void installSystemProviders() {
9782        List<ProviderInfo> providers;
9783        synchronized (this) {
9784            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9785            providers = generateApplicationProvidersLocked(app);
9786            if (providers != null) {
9787                for (int i=providers.size()-1; i>=0; i--) {
9788                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9789                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9790                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9791                                + ": not system .apk");
9792                        providers.remove(i);
9793                    }
9794                }
9795            }
9796        }
9797        if (providers != null) {
9798            mSystemThread.installSystemProviders(providers);
9799        }
9800
9801        mCoreSettingsObserver = new CoreSettingsObserver(this);
9802
9803        //mUsageStatsService.monitorPackages();
9804    }
9805
9806    /**
9807     * Allows apps to retrieve the MIME type of a URI.
9808     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9809     * users, then it does not need permission to access the ContentProvider.
9810     * Either, it needs cross-user uri grants.
9811     *
9812     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9813     *
9814     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9815     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9816     */
9817    public String getProviderMimeType(Uri uri, int userId) {
9818        enforceNotIsolatedCaller("getProviderMimeType");
9819        final String name = uri.getAuthority();
9820        int callingUid = Binder.getCallingUid();
9821        int callingPid = Binder.getCallingPid();
9822        long ident = 0;
9823        boolean clearedIdentity = false;
9824        userId = unsafeConvertIncomingUser(userId);
9825        if (canClearIdentity(callingPid, callingUid, userId)) {
9826            clearedIdentity = true;
9827            ident = Binder.clearCallingIdentity();
9828        }
9829        ContentProviderHolder holder = null;
9830        try {
9831            holder = getContentProviderExternalUnchecked(name, null, userId);
9832            if (holder != null) {
9833                return holder.provider.getType(uri);
9834            }
9835        } catch (RemoteException e) {
9836            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9837            return null;
9838        } finally {
9839            // We need to clear the identity to call removeContentProviderExternalUnchecked
9840            if (!clearedIdentity) {
9841                ident = Binder.clearCallingIdentity();
9842            }
9843            try {
9844                if (holder != null) {
9845                    removeContentProviderExternalUnchecked(name, null, userId);
9846                }
9847            } finally {
9848                Binder.restoreCallingIdentity(ident);
9849            }
9850        }
9851
9852        return null;
9853    }
9854
9855    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9856        if (UserHandle.getUserId(callingUid) == userId) {
9857            return true;
9858        }
9859        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9860                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9861                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9862                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9863                return true;
9864        }
9865        return false;
9866    }
9867
9868    // =========================================================
9869    // GLOBAL MANAGEMENT
9870    // =========================================================
9871
9872    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9873            boolean isolated, int isolatedUid) {
9874        String proc = customProcess != null ? customProcess : info.processName;
9875        BatteryStatsImpl.Uid.Proc ps = null;
9876        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9877        int uid = info.uid;
9878        if (isolated) {
9879            if (isolatedUid == 0) {
9880                int userId = UserHandle.getUserId(uid);
9881                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9882                while (true) {
9883                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9884                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9885                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9886                    }
9887                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9888                    mNextIsolatedProcessUid++;
9889                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9890                        // No process for this uid, use it.
9891                        break;
9892                    }
9893                    stepsLeft--;
9894                    if (stepsLeft <= 0) {
9895                        return null;
9896                    }
9897                }
9898            } else {
9899                // Special case for startIsolatedProcess (internal only), where
9900                // the uid of the isolated process is specified by the caller.
9901                uid = isolatedUid;
9902            }
9903        }
9904        return new ProcessRecord(stats, info, proc, uid);
9905    }
9906
9907    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9908            String abiOverride) {
9909        ProcessRecord app;
9910        if (!isolated) {
9911            app = getProcessRecordLocked(info.processName, info.uid, true);
9912        } else {
9913            app = null;
9914        }
9915
9916        if (app == null) {
9917            app = newProcessRecordLocked(info, null, isolated, 0);
9918            mProcessNames.put(info.processName, app.uid, app);
9919            if (isolated) {
9920                mIsolatedProcesses.put(app.uid, app);
9921            }
9922            updateLruProcessLocked(app, false, null);
9923            updateOomAdjLocked();
9924        }
9925
9926        // This package really, really can not be stopped.
9927        try {
9928            AppGlobals.getPackageManager().setPackageStoppedState(
9929                    info.packageName, false, UserHandle.getUserId(app.uid));
9930        } catch (RemoteException e) {
9931        } catch (IllegalArgumentException e) {
9932            Slog.w(TAG, "Failed trying to unstop package "
9933                    + info.packageName + ": " + e);
9934        }
9935
9936        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9937                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9938            app.persistent = true;
9939            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9940        }
9941        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9942            mPersistentStartingProcesses.add(app);
9943            startProcessLocked(app, "added application", app.processName, abiOverride,
9944                    null /* entryPoint */, null /* entryPointArgs */);
9945        }
9946
9947        return app;
9948    }
9949
9950    public void unhandledBack() {
9951        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9952                "unhandledBack()");
9953
9954        synchronized(this) {
9955            final long origId = Binder.clearCallingIdentity();
9956            try {
9957                getFocusedStack().unhandledBackLocked();
9958            } finally {
9959                Binder.restoreCallingIdentity(origId);
9960            }
9961        }
9962    }
9963
9964    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9965        enforceNotIsolatedCaller("openContentUri");
9966        final int userId = UserHandle.getCallingUserId();
9967        String name = uri.getAuthority();
9968        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9969        ParcelFileDescriptor pfd = null;
9970        if (cph != null) {
9971            // We record the binder invoker's uid in thread-local storage before
9972            // going to the content provider to open the file.  Later, in the code
9973            // that handles all permissions checks, we look for this uid and use
9974            // that rather than the Activity Manager's own uid.  The effect is that
9975            // we do the check against the caller's permissions even though it looks
9976            // to the content provider like the Activity Manager itself is making
9977            // the request.
9978            Binder token = new Binder();
9979            sCallerIdentity.set(new Identity(
9980                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9981            try {
9982                pfd = cph.provider.openFile(null, uri, "r", null, token);
9983            } catch (FileNotFoundException e) {
9984                // do nothing; pfd will be returned null
9985            } finally {
9986                // Ensure that whatever happens, we clean up the identity state
9987                sCallerIdentity.remove();
9988            }
9989
9990            // We've got the fd now, so we're done with the provider.
9991            removeContentProviderExternalUnchecked(name, null, userId);
9992        } else {
9993            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9994        }
9995        return pfd;
9996    }
9997
9998    // Actually is sleeping or shutting down or whatever else in the future
9999    // is an inactive state.
10000    public boolean isSleepingOrShuttingDown() {
10001        return isSleeping() || mShuttingDown;
10002    }
10003
10004    public boolean isSleeping() {
10005        return mSleeping;
10006    }
10007
10008    void onWakefulnessChanged(int wakefulness) {
10009        synchronized(this) {
10010            mWakefulness = wakefulness;
10011            updateSleepIfNeededLocked();
10012        }
10013    }
10014
10015    void finishRunningVoiceLocked() {
10016        if (mRunningVoice) {
10017            mRunningVoice = false;
10018            updateSleepIfNeededLocked();
10019        }
10020    }
10021
10022    void updateSleepIfNeededLocked() {
10023        if (mSleeping && !shouldSleepLocked()) {
10024            mSleeping = false;
10025            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10026        } else if (!mSleeping && shouldSleepLocked()) {
10027            mSleeping = true;
10028            mStackSupervisor.goingToSleepLocked();
10029
10030            // Initialize the wake times of all processes.
10031            checkExcessivePowerUsageLocked(false);
10032            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10033            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10034            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10035        }
10036    }
10037
10038    private boolean shouldSleepLocked() {
10039        // Resume applications while running a voice interactor.
10040        if (mRunningVoice) {
10041            return false;
10042        }
10043
10044        switch (mWakefulness) {
10045            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10046            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10047                // If we're interactive but applications are already paused then defer
10048                // resuming them until the lock screen is hidden.
10049                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10050            case PowerManagerInternal.WAKEFULNESS_DOZING:
10051                // If we're dozing then pause applications whenever the lock screen is shown.
10052                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10053            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10054            default:
10055                // If we're asleep then pause applications unconditionally.
10056                return true;
10057        }
10058    }
10059
10060    /** Pokes the task persister. */
10061    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10062        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10063            // Never persist the home stack.
10064            return;
10065        }
10066        mTaskPersister.wakeup(task, flush);
10067    }
10068
10069    /** Notifies all listeners when the task stack has changed. */
10070    void notifyTaskStackChangedLocked() {
10071        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10072        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10073        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10074    }
10075
10076    @Override
10077    public boolean shutdown(int timeout) {
10078        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10079                != PackageManager.PERMISSION_GRANTED) {
10080            throw new SecurityException("Requires permission "
10081                    + android.Manifest.permission.SHUTDOWN);
10082        }
10083
10084        boolean timedout = false;
10085
10086        synchronized(this) {
10087            mShuttingDown = true;
10088            updateEventDispatchingLocked();
10089            timedout = mStackSupervisor.shutdownLocked(timeout);
10090        }
10091
10092        mAppOpsService.shutdown();
10093        if (mUsageStatsService != null) {
10094            mUsageStatsService.prepareShutdown();
10095        }
10096        mBatteryStatsService.shutdown();
10097        synchronized (this) {
10098            mProcessStats.shutdownLocked();
10099            notifyTaskPersisterLocked(null, true);
10100        }
10101
10102        return timedout;
10103    }
10104
10105    public final void activitySlept(IBinder token) {
10106        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10107
10108        final long origId = Binder.clearCallingIdentity();
10109
10110        synchronized (this) {
10111            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10112            if (r != null) {
10113                mStackSupervisor.activitySleptLocked(r);
10114            }
10115        }
10116
10117        Binder.restoreCallingIdentity(origId);
10118    }
10119
10120    private String lockScreenShownToString() {
10121        switch (mLockScreenShown) {
10122            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10123            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10124            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10125            default: return "Unknown=" + mLockScreenShown;
10126        }
10127    }
10128
10129    void logLockScreen(String msg) {
10130        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10131                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10132                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10133                + " mSleeping=" + mSleeping);
10134    }
10135
10136    void startRunningVoiceLocked() {
10137        if (!mRunningVoice) {
10138            mRunningVoice = true;
10139            updateSleepIfNeededLocked();
10140        }
10141    }
10142
10143    private void updateEventDispatchingLocked() {
10144        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10145    }
10146
10147    public void setLockScreenShown(boolean shown) {
10148        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10149                != PackageManager.PERMISSION_GRANTED) {
10150            throw new SecurityException("Requires permission "
10151                    + android.Manifest.permission.DEVICE_POWER);
10152        }
10153
10154        synchronized(this) {
10155            long ident = Binder.clearCallingIdentity();
10156            try {
10157                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10158                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10159                updateSleepIfNeededLocked();
10160            } finally {
10161                Binder.restoreCallingIdentity(ident);
10162            }
10163        }
10164    }
10165
10166    @Override
10167    public void stopAppSwitches() {
10168        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10169                != PackageManager.PERMISSION_GRANTED) {
10170            throw new SecurityException("Requires permission "
10171                    + android.Manifest.permission.STOP_APP_SWITCHES);
10172        }
10173
10174        synchronized(this) {
10175            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10176                    + APP_SWITCH_DELAY_TIME;
10177            mDidAppSwitch = false;
10178            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10179            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10180            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10181        }
10182    }
10183
10184    public void resumeAppSwitches() {
10185        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10186                != PackageManager.PERMISSION_GRANTED) {
10187            throw new SecurityException("Requires permission "
10188                    + android.Manifest.permission.STOP_APP_SWITCHES);
10189        }
10190
10191        synchronized(this) {
10192            // Note that we don't execute any pending app switches... we will
10193            // let those wait until either the timeout, or the next start
10194            // activity request.
10195            mAppSwitchesAllowedTime = 0;
10196        }
10197    }
10198
10199    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10200            int callingPid, int callingUid, String name) {
10201        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10202            return true;
10203        }
10204
10205        int perm = checkComponentPermission(
10206                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10207                sourceUid, -1, true);
10208        if (perm == PackageManager.PERMISSION_GRANTED) {
10209            return true;
10210        }
10211
10212        // If the actual IPC caller is different from the logical source, then
10213        // also see if they are allowed to control app switches.
10214        if (callingUid != -1 && callingUid != sourceUid) {
10215            perm = checkComponentPermission(
10216                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10217                    callingUid, -1, true);
10218            if (perm == PackageManager.PERMISSION_GRANTED) {
10219                return true;
10220            }
10221        }
10222
10223        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10224        return false;
10225    }
10226
10227    public void setDebugApp(String packageName, boolean waitForDebugger,
10228            boolean persistent) {
10229        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10230                "setDebugApp()");
10231
10232        long ident = Binder.clearCallingIdentity();
10233        try {
10234            // Note that this is not really thread safe if there are multiple
10235            // callers into it at the same time, but that's not a situation we
10236            // care about.
10237            if (persistent) {
10238                final ContentResolver resolver = mContext.getContentResolver();
10239                Settings.Global.putString(
10240                    resolver, Settings.Global.DEBUG_APP,
10241                    packageName);
10242                Settings.Global.putInt(
10243                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10244                    waitForDebugger ? 1 : 0);
10245            }
10246
10247            synchronized (this) {
10248                if (!persistent) {
10249                    mOrigDebugApp = mDebugApp;
10250                    mOrigWaitForDebugger = mWaitForDebugger;
10251                }
10252                mDebugApp = packageName;
10253                mWaitForDebugger = waitForDebugger;
10254                mDebugTransient = !persistent;
10255                if (packageName != null) {
10256                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10257                            false, UserHandle.USER_ALL, "set debug app");
10258                }
10259            }
10260        } finally {
10261            Binder.restoreCallingIdentity(ident);
10262        }
10263    }
10264
10265    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10266        synchronized (this) {
10267            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10268            if (!isDebuggable) {
10269                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10270                    throw new SecurityException("Process not debuggable: " + app.packageName);
10271                }
10272            }
10273
10274            mOpenGlTraceApp = processName;
10275        }
10276    }
10277
10278    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10279        synchronized (this) {
10280            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10281            if (!isDebuggable) {
10282                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10283                    throw new SecurityException("Process not debuggable: " + app.packageName);
10284                }
10285            }
10286            mProfileApp = processName;
10287            mProfileFile = profilerInfo.profileFile;
10288            if (mProfileFd != null) {
10289                try {
10290                    mProfileFd.close();
10291                } catch (IOException e) {
10292                }
10293                mProfileFd = null;
10294            }
10295            mProfileFd = profilerInfo.profileFd;
10296            mSamplingInterval = profilerInfo.samplingInterval;
10297            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10298            mProfileType = 0;
10299        }
10300    }
10301
10302    @Override
10303    public void setAlwaysFinish(boolean enabled) {
10304        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10305                "setAlwaysFinish()");
10306
10307        Settings.Global.putInt(
10308                mContext.getContentResolver(),
10309                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10310
10311        synchronized (this) {
10312            mAlwaysFinishActivities = enabled;
10313        }
10314    }
10315
10316    @Override
10317    public void setActivityController(IActivityController controller) {
10318        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10319                "setActivityController()");
10320        synchronized (this) {
10321            mController = controller;
10322            Watchdog.getInstance().setActivityController(controller);
10323        }
10324    }
10325
10326    @Override
10327    public void setUserIsMonkey(boolean userIsMonkey) {
10328        synchronized (this) {
10329            synchronized (mPidsSelfLocked) {
10330                final int callingPid = Binder.getCallingPid();
10331                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10332                if (precessRecord == null) {
10333                    throw new SecurityException("Unknown process: " + callingPid);
10334                }
10335                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10336                    throw new SecurityException("Only an instrumentation process "
10337                            + "with a UiAutomation can call setUserIsMonkey");
10338                }
10339            }
10340            mUserIsMonkey = userIsMonkey;
10341        }
10342    }
10343
10344    @Override
10345    public boolean isUserAMonkey() {
10346        synchronized (this) {
10347            // If there is a controller also implies the user is a monkey.
10348            return (mUserIsMonkey || mController != null);
10349        }
10350    }
10351
10352    public void requestBugReport() {
10353        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10354        SystemProperties.set("ctl.start", "bugreport");
10355    }
10356
10357    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10358        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10359    }
10360
10361    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10362        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10363            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10364        }
10365        return KEY_DISPATCHING_TIMEOUT;
10366    }
10367
10368    @Override
10369    public long inputDispatchingTimedOut(int pid, 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        ProcessRecord proc;
10376        long timeout;
10377        synchronized (this) {
10378            synchronized (mPidsSelfLocked) {
10379                proc = mPidsSelfLocked.get(pid);
10380            }
10381            timeout = getInputDispatchingTimeoutLocked(proc);
10382        }
10383
10384        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10385            return -1;
10386        }
10387
10388        return timeout;
10389    }
10390
10391    /**
10392     * Handle input dispatching timeouts.
10393     * Returns whether input dispatching should be aborted or not.
10394     */
10395    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10396            final ActivityRecord activity, final ActivityRecord parent,
10397            final boolean aboveSystem, String reason) {
10398        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10399                != PackageManager.PERMISSION_GRANTED) {
10400            throw new SecurityException("Requires permission "
10401                    + android.Manifest.permission.FILTER_EVENTS);
10402        }
10403
10404        final String annotation;
10405        if (reason == null) {
10406            annotation = "Input dispatching timed out";
10407        } else {
10408            annotation = "Input dispatching timed out (" + reason + ")";
10409        }
10410
10411        if (proc != null) {
10412            synchronized (this) {
10413                if (proc.debugging) {
10414                    return false;
10415                }
10416
10417                if (mDidDexOpt) {
10418                    // Give more time since we were dexopting.
10419                    mDidDexOpt = false;
10420                    return false;
10421                }
10422
10423                if (proc.instrumentationClass != null) {
10424                    Bundle info = new Bundle();
10425                    info.putString("shortMsg", "keyDispatchingTimedOut");
10426                    info.putString("longMsg", annotation);
10427                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10428                    return true;
10429                }
10430            }
10431            mHandler.post(new Runnable() {
10432                @Override
10433                public void run() {
10434                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10435                }
10436            });
10437        }
10438
10439        return true;
10440    }
10441
10442    public Bundle getAssistContextExtras(int requestType) {
10443        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10444                UserHandle.getCallingUserId());
10445        if (pae == null) {
10446            return null;
10447        }
10448        synchronized (pae) {
10449            while (!pae.haveResult) {
10450                try {
10451                    pae.wait();
10452                } catch (InterruptedException e) {
10453                }
10454            }
10455            if (pae.result != null) {
10456                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10457            }
10458        }
10459        synchronized (this) {
10460            mPendingAssistExtras.remove(pae);
10461            mHandler.removeCallbacks(pae);
10462        }
10463        return pae.extras;
10464    }
10465
10466    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10467            int userHandle) {
10468        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10469                "getAssistContextExtras()");
10470        PendingAssistExtras pae;
10471        Bundle extras = new Bundle();
10472        synchronized (this) {
10473            ActivityRecord activity = getFocusedStack().mResumedActivity;
10474            if (activity == null) {
10475                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10476                return null;
10477            }
10478            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10479            if (activity.app == null || activity.app.thread == null) {
10480                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10481                return null;
10482            }
10483            if (activity.app.pid == Binder.getCallingPid()) {
10484                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10485                return null;
10486            }
10487            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10488            try {
10489                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10490                        requestType);
10491                mPendingAssistExtras.add(pae);
10492                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10493            } catch (RemoteException e) {
10494                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10495                return null;
10496            }
10497            return pae;
10498        }
10499    }
10500
10501    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10502        PendingAssistExtras pae = (PendingAssistExtras)token;
10503        synchronized (pae) {
10504            pae.result = extras;
10505            pae.haveResult = true;
10506            pae.notifyAll();
10507            if (pae.intent == null) {
10508                // Caller is just waiting for the result.
10509                return;
10510            }
10511        }
10512
10513        // We are now ready to launch the assist activity.
10514        synchronized (this) {
10515            boolean exists = mPendingAssistExtras.remove(pae);
10516            mHandler.removeCallbacks(pae);
10517            if (!exists) {
10518                // Timed out.
10519                return;
10520            }
10521        }
10522        pae.intent.replaceExtras(extras);
10523        if (pae.hint != null) {
10524            pae.intent.putExtra(pae.hint, true);
10525        }
10526        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10527                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10528                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10529        closeSystemDialogs("assist");
10530        try {
10531            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10532        } catch (ActivityNotFoundException e) {
10533            Slog.w(TAG, "No activity to handle assist action.", e);
10534        }
10535    }
10536
10537    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10538        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10539    }
10540
10541    public void registerProcessObserver(IProcessObserver observer) {
10542        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10543                "registerProcessObserver()");
10544        synchronized (this) {
10545            mProcessObservers.register(observer);
10546        }
10547    }
10548
10549    @Override
10550    public void unregisterProcessObserver(IProcessObserver observer) {
10551        synchronized (this) {
10552            mProcessObservers.unregister(observer);
10553        }
10554    }
10555
10556    @Override
10557    public boolean convertFromTranslucent(IBinder token) {
10558        final long origId = Binder.clearCallingIdentity();
10559        try {
10560            synchronized (this) {
10561                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10562                if (r == null) {
10563                    return false;
10564                }
10565                final boolean translucentChanged = r.changeWindowTranslucency(true);
10566                if (translucentChanged) {
10567                    r.task.stack.releaseBackgroundResources();
10568                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10569                }
10570                mWindowManager.setAppFullscreen(token, true);
10571                return translucentChanged;
10572            }
10573        } finally {
10574            Binder.restoreCallingIdentity(origId);
10575        }
10576    }
10577
10578    @Override
10579    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10580        final long origId = Binder.clearCallingIdentity();
10581        try {
10582            synchronized (this) {
10583                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10584                if (r == null) {
10585                    return false;
10586                }
10587                int index = r.task.mActivities.lastIndexOf(r);
10588                if (index > 0) {
10589                    ActivityRecord under = r.task.mActivities.get(index - 1);
10590                    under.returningOptions = options;
10591                }
10592                final boolean translucentChanged = r.changeWindowTranslucency(false);
10593                if (translucentChanged) {
10594                    r.task.stack.convertToTranslucent(r);
10595                }
10596                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10597                mWindowManager.setAppFullscreen(token, false);
10598                return translucentChanged;
10599            }
10600        } finally {
10601            Binder.restoreCallingIdentity(origId);
10602        }
10603    }
10604
10605    @Override
10606    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10607        final long origId = Binder.clearCallingIdentity();
10608        try {
10609            synchronized (this) {
10610                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10611                if (r != null) {
10612                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10613                }
10614            }
10615            return false;
10616        } finally {
10617            Binder.restoreCallingIdentity(origId);
10618        }
10619    }
10620
10621    @Override
10622    public boolean isBackgroundVisibleBehind(IBinder token) {
10623        final long origId = Binder.clearCallingIdentity();
10624        try {
10625            synchronized (this) {
10626                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10627                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10628                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10629                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10630                return visible;
10631            }
10632        } finally {
10633            Binder.restoreCallingIdentity(origId);
10634        }
10635    }
10636
10637    @Override
10638    public ActivityOptions getActivityOptions(IBinder token) {
10639        final long origId = Binder.clearCallingIdentity();
10640        try {
10641            synchronized (this) {
10642                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10643                if (r != null) {
10644                    final ActivityOptions activityOptions = r.pendingOptions;
10645                    r.pendingOptions = null;
10646                    return activityOptions;
10647                }
10648                return null;
10649            }
10650        } finally {
10651            Binder.restoreCallingIdentity(origId);
10652        }
10653    }
10654
10655    @Override
10656    public void setImmersive(IBinder token, boolean immersive) {
10657        synchronized(this) {
10658            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10659            if (r == null) {
10660                throw new IllegalArgumentException();
10661            }
10662            r.immersive = immersive;
10663
10664            // update associated state if we're frontmost
10665            if (r == mFocusedActivity) {
10666                if (DEBUG_IMMERSIVE) {
10667                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10668                }
10669                applyUpdateLockStateLocked(r);
10670            }
10671        }
10672    }
10673
10674    @Override
10675    public boolean isImmersive(IBinder token) {
10676        synchronized (this) {
10677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10678            if (r == null) {
10679                throw new IllegalArgumentException();
10680            }
10681            return r.immersive;
10682        }
10683    }
10684
10685    public boolean isTopActivityImmersive() {
10686        enforceNotIsolatedCaller("startActivity");
10687        synchronized (this) {
10688            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10689            return (r != null) ? r.immersive : false;
10690        }
10691    }
10692
10693    @Override
10694    public boolean isTopOfTask(IBinder token) {
10695        synchronized (this) {
10696            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10697            if (r == null) {
10698                throw new IllegalArgumentException();
10699            }
10700            return r.task.getTopActivity() == r;
10701        }
10702    }
10703
10704    public final void enterSafeMode() {
10705        synchronized(this) {
10706            // It only makes sense to do this before the system is ready
10707            // and started launching other packages.
10708            if (!mSystemReady) {
10709                try {
10710                    AppGlobals.getPackageManager().enterSafeMode();
10711                } catch (RemoteException e) {
10712                }
10713            }
10714
10715            mSafeMode = true;
10716        }
10717    }
10718
10719    public final void showSafeModeOverlay() {
10720        View v = LayoutInflater.from(mContext).inflate(
10721                com.android.internal.R.layout.safe_mode, null);
10722        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10723        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10724        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10725        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10726        lp.gravity = Gravity.BOTTOM | Gravity.START;
10727        lp.format = v.getBackground().getOpacity();
10728        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10729                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10730        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10731        ((WindowManager)mContext.getSystemService(
10732                Context.WINDOW_SERVICE)).addView(v, lp);
10733    }
10734
10735    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10736        if (!(sender instanceof PendingIntentRecord)) {
10737            return;
10738        }
10739        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10740        synchronized (stats) {
10741            if (mBatteryStatsService.isOnBattery()) {
10742                mBatteryStatsService.enforceCallingPermission();
10743                PendingIntentRecord rec = (PendingIntentRecord)sender;
10744                int MY_UID = Binder.getCallingUid();
10745                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10746                BatteryStatsImpl.Uid.Pkg pkg =
10747                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10748                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10749                pkg.incWakeupsLocked();
10750            }
10751        }
10752    }
10753
10754    public boolean killPids(int[] pids, String pReason, boolean secure) {
10755        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10756            throw new SecurityException("killPids only available to the system");
10757        }
10758        String reason = (pReason == null) ? "Unknown" : pReason;
10759        // XXX Note: don't acquire main activity lock here, because the window
10760        // manager calls in with its locks held.
10761
10762        boolean killed = false;
10763        synchronized (mPidsSelfLocked) {
10764            int[] types = new int[pids.length];
10765            int worstType = 0;
10766            for (int i=0; i<pids.length; i++) {
10767                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10768                if (proc != null) {
10769                    int type = proc.setAdj;
10770                    types[i] = type;
10771                    if (type > worstType) {
10772                        worstType = type;
10773                    }
10774                }
10775            }
10776
10777            // If the worst oom_adj is somewhere in the cached proc LRU range,
10778            // then constrain it so we will kill all cached procs.
10779            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10780                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10781                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10782            }
10783
10784            // If this is not a secure call, don't let it kill processes that
10785            // are important.
10786            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10787                worstType = ProcessList.SERVICE_ADJ;
10788            }
10789
10790            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10791            for (int i=0; i<pids.length; i++) {
10792                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10793                if (proc == null) {
10794                    continue;
10795                }
10796                int adj = proc.setAdj;
10797                if (adj >= worstType && !proc.killedByAm) {
10798                    proc.kill(reason, true);
10799                    killed = true;
10800                }
10801            }
10802        }
10803        return killed;
10804    }
10805
10806    @Override
10807    public void killUid(int uid, String reason) {
10808        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10809            throw new SecurityException("killUid only available to the system");
10810        }
10811        synchronized (this) {
10812            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10813                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10814                    reason != null ? reason : "kill uid");
10815        }
10816    }
10817
10818    @Override
10819    public boolean killProcessesBelowForeground(String reason) {
10820        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10821            throw new SecurityException("killProcessesBelowForeground() only available to system");
10822        }
10823
10824        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10825    }
10826
10827    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10828        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10829            throw new SecurityException("killProcessesBelowAdj() only available to system");
10830        }
10831
10832        boolean killed = false;
10833        synchronized (mPidsSelfLocked) {
10834            final int size = mPidsSelfLocked.size();
10835            for (int i = 0; i < size; i++) {
10836                final int pid = mPidsSelfLocked.keyAt(i);
10837                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10838                if (proc == null) continue;
10839
10840                final int adj = proc.setAdj;
10841                if (adj > belowAdj && !proc.killedByAm) {
10842                    proc.kill(reason, true);
10843                    killed = true;
10844                }
10845            }
10846        }
10847        return killed;
10848    }
10849
10850    @Override
10851    public void hang(final IBinder who, boolean allowRestart) {
10852        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10853                != PackageManager.PERMISSION_GRANTED) {
10854            throw new SecurityException("Requires permission "
10855                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10856        }
10857
10858        final IBinder.DeathRecipient death = new DeathRecipient() {
10859            @Override
10860            public void binderDied() {
10861                synchronized (this) {
10862                    notifyAll();
10863                }
10864            }
10865        };
10866
10867        try {
10868            who.linkToDeath(death, 0);
10869        } catch (RemoteException e) {
10870            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10871            return;
10872        }
10873
10874        synchronized (this) {
10875            Watchdog.getInstance().setAllowRestart(allowRestart);
10876            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10877            synchronized (death) {
10878                while (who.isBinderAlive()) {
10879                    try {
10880                        death.wait();
10881                    } catch (InterruptedException e) {
10882                    }
10883                }
10884            }
10885            Watchdog.getInstance().setAllowRestart(true);
10886        }
10887    }
10888
10889    @Override
10890    public void restart() {
10891        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10892                != PackageManager.PERMISSION_GRANTED) {
10893            throw new SecurityException("Requires permission "
10894                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10895        }
10896
10897        Log.i(TAG, "Sending shutdown broadcast...");
10898
10899        BroadcastReceiver br = new BroadcastReceiver() {
10900            @Override public void onReceive(Context context, Intent intent) {
10901                // Now the broadcast is done, finish up the low-level shutdown.
10902                Log.i(TAG, "Shutting down activity manager...");
10903                shutdown(10000);
10904                Log.i(TAG, "Shutdown complete, restarting!");
10905                Process.killProcess(Process.myPid());
10906                System.exit(10);
10907            }
10908        };
10909
10910        // First send the high-level shut down broadcast.
10911        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10912        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10913        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10914        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10915        mContext.sendOrderedBroadcastAsUser(intent,
10916                UserHandle.ALL, null, br, mHandler, 0, null, null);
10917        */
10918        br.onReceive(mContext, intent);
10919    }
10920
10921    private long getLowRamTimeSinceIdle(long now) {
10922        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10923    }
10924
10925    @Override
10926    public void performIdleMaintenance() {
10927        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10928                != PackageManager.PERMISSION_GRANTED) {
10929            throw new SecurityException("Requires permission "
10930                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10931        }
10932
10933        synchronized (this) {
10934            final long now = SystemClock.uptimeMillis();
10935            final long timeSinceLastIdle = now - mLastIdleTime;
10936            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10937            mLastIdleTime = now;
10938            mLowRamTimeSinceLastIdle = 0;
10939            if (mLowRamStartTime != 0) {
10940                mLowRamStartTime = now;
10941            }
10942
10943            StringBuilder sb = new StringBuilder(128);
10944            sb.append("Idle maintenance over ");
10945            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10946            sb.append(" low RAM for ");
10947            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10948            Slog.i(TAG, sb.toString());
10949
10950            // If at least 1/3 of our time since the last idle period has been spent
10951            // with RAM low, then we want to kill processes.
10952            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10953
10954            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10955                ProcessRecord proc = mLruProcesses.get(i);
10956                if (proc.notCachedSinceIdle) {
10957                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10958                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10959                        if (doKilling && proc.initialIdlePss != 0
10960                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10961                            sb = new StringBuilder(128);
10962                            sb.append("Kill");
10963                            sb.append(proc.processName);
10964                            sb.append(" in idle maint: pss=");
10965                            sb.append(proc.lastPss);
10966                            sb.append(", initialPss=");
10967                            sb.append(proc.initialIdlePss);
10968                            sb.append(", period=");
10969                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10970                            sb.append(", lowRamPeriod=");
10971                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10972                            Slog.wtfQuiet(TAG, sb.toString());
10973                            proc.kill("idle maint (pss " + proc.lastPss
10974                                    + " from " + proc.initialIdlePss + ")", true);
10975                        }
10976                    }
10977                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10978                    proc.notCachedSinceIdle = true;
10979                    proc.initialIdlePss = 0;
10980                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10981                            mTestPssMode, isSleeping(), now);
10982                }
10983            }
10984
10985            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10986            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10987        }
10988    }
10989
10990    private void retrieveSettings() {
10991        final ContentResolver resolver = mContext.getContentResolver();
10992        String debugApp = Settings.Global.getString(
10993            resolver, Settings.Global.DEBUG_APP);
10994        boolean waitForDebugger = Settings.Global.getInt(
10995            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10996        boolean alwaysFinishActivities = Settings.Global.getInt(
10997            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10998        boolean forceRtl = Settings.Global.getInt(
10999                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11000        // Transfer any global setting for forcing RTL layout, into a System Property
11001        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11002
11003        Configuration configuration = new Configuration();
11004        Settings.System.getConfiguration(resolver, configuration);
11005        if (forceRtl) {
11006            // This will take care of setting the correct layout direction flags
11007            configuration.setLayoutDirection(configuration.locale);
11008        }
11009
11010        synchronized (this) {
11011            mDebugApp = mOrigDebugApp = debugApp;
11012            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11013            mAlwaysFinishActivities = alwaysFinishActivities;
11014            // This happens before any activities are started, so we can
11015            // change mConfiguration in-place.
11016            updateConfigurationLocked(configuration, null, false, true);
11017            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11018        }
11019    }
11020
11021    /** Loads resources after the current configuration has been set. */
11022    private void loadResourcesOnSystemReady() {
11023        final Resources res = mContext.getResources();
11024        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11025        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11026        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11027    }
11028
11029    public boolean testIsSystemReady() {
11030        // no need to synchronize(this) just to read & return the value
11031        return mSystemReady;
11032    }
11033
11034    private static File getCalledPreBootReceiversFile() {
11035        File dataDir = Environment.getDataDirectory();
11036        File systemDir = new File(dataDir, "system");
11037        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11038        return fname;
11039    }
11040
11041    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11042        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11043        File file = getCalledPreBootReceiversFile();
11044        FileInputStream fis = null;
11045        try {
11046            fis = new FileInputStream(file);
11047            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11048            int fvers = dis.readInt();
11049            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11050                String vers = dis.readUTF();
11051                String codename = dis.readUTF();
11052                String build = dis.readUTF();
11053                if (android.os.Build.VERSION.RELEASE.equals(vers)
11054                        && android.os.Build.VERSION.CODENAME.equals(codename)
11055                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11056                    int num = dis.readInt();
11057                    while (num > 0) {
11058                        num--;
11059                        String pkg = dis.readUTF();
11060                        String cls = dis.readUTF();
11061                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11062                    }
11063                }
11064            }
11065        } catch (FileNotFoundException e) {
11066        } catch (IOException e) {
11067            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11068        } finally {
11069            if (fis != null) {
11070                try {
11071                    fis.close();
11072                } catch (IOException e) {
11073                }
11074            }
11075        }
11076        return lastDoneReceivers;
11077    }
11078
11079    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11080        File file = getCalledPreBootReceiversFile();
11081        FileOutputStream fos = null;
11082        DataOutputStream dos = null;
11083        try {
11084            fos = new FileOutputStream(file);
11085            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11086            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11087            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11088            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11089            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11090            dos.writeInt(list.size());
11091            for (int i=0; i<list.size(); i++) {
11092                dos.writeUTF(list.get(i).getPackageName());
11093                dos.writeUTF(list.get(i).getClassName());
11094            }
11095        } catch (IOException e) {
11096            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11097            file.delete();
11098        } finally {
11099            FileUtils.sync(fos);
11100            if (dos != null) {
11101                try {
11102                    dos.close();
11103                } catch (IOException e) {
11104                    // TODO Auto-generated catch block
11105                    e.printStackTrace();
11106                }
11107            }
11108        }
11109    }
11110
11111    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11112            ArrayList<ComponentName> doneReceivers, int userId) {
11113        boolean waitingUpdate = false;
11114        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11115        List<ResolveInfo> ris = null;
11116        try {
11117            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11118                    intent, null, 0, userId);
11119        } catch (RemoteException e) {
11120        }
11121        if (ris != null) {
11122            for (int i=ris.size()-1; i>=0; i--) {
11123                if ((ris.get(i).activityInfo.applicationInfo.flags
11124                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11125                    ris.remove(i);
11126                }
11127            }
11128            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11129
11130            // For User 0, load the version number. When delivering to a new user, deliver
11131            // to all receivers.
11132            if (userId == UserHandle.USER_OWNER) {
11133                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11134                for (int i=0; i<ris.size(); i++) {
11135                    ActivityInfo ai = ris.get(i).activityInfo;
11136                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11137                    if (lastDoneReceivers.contains(comp)) {
11138                        // We already did the pre boot receiver for this app with the current
11139                        // platform version, so don't do it again...
11140                        ris.remove(i);
11141                        i--;
11142                        // ...however, do keep it as one that has been done, so we don't
11143                        // forget about it when rewriting the file of last done receivers.
11144                        doneReceivers.add(comp);
11145                    }
11146                }
11147            }
11148
11149            // If primary user, send broadcast to all available users, else just to userId
11150            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11151                    : new int[] { userId };
11152            for (int i = 0; i < ris.size(); i++) {
11153                ActivityInfo ai = ris.get(i).activityInfo;
11154                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11155                doneReceivers.add(comp);
11156                intent.setComponent(comp);
11157                for (int j=0; j<users.length; j++) {
11158                    IIntentReceiver finisher = null;
11159                    // On last receiver and user, set up a completion callback
11160                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11161                        finisher = new IIntentReceiver.Stub() {
11162                            public void performReceive(Intent intent, int resultCode,
11163                                    String data, Bundle extras, boolean ordered,
11164                                    boolean sticky, int sendingUser) {
11165                                // The raw IIntentReceiver interface is called
11166                                // with the AM lock held, so redispatch to
11167                                // execute our code without the lock.
11168                                mHandler.post(onFinishCallback);
11169                            }
11170                        };
11171                    }
11172                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11173                            + " for user " + users[j]);
11174                    broadcastIntentLocked(null, null, intent, null, finisher,
11175                            0, null, null, null, AppOpsManager.OP_NONE,
11176                            true, false, MY_PID, Process.SYSTEM_UID,
11177                            users[j]);
11178                    if (finisher != null) {
11179                        waitingUpdate = true;
11180                    }
11181                }
11182            }
11183        }
11184
11185        return waitingUpdate;
11186    }
11187
11188    public void systemReady(final Runnable goingCallback) {
11189        synchronized(this) {
11190            if (mSystemReady) {
11191                // If we're done calling all the receivers, run the next "boot phase" passed in
11192                // by the SystemServer
11193                if (goingCallback != null) {
11194                    goingCallback.run();
11195                }
11196                return;
11197            }
11198
11199            // Make sure we have the current profile info, since it is needed for
11200            // security checks.
11201            updateCurrentProfileIdsLocked();
11202
11203            if (mRecentTasks == null) {
11204                mRecentTasks = mTaskPersister.restoreTasksLocked();
11205                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11206                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11207                mTaskPersister.startPersisting();
11208            }
11209
11210            // Check to see if there are any update receivers to run.
11211            if (!mDidUpdate) {
11212                if (mWaitingUpdate) {
11213                    return;
11214                }
11215                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11216                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11217                    public void run() {
11218                        synchronized (ActivityManagerService.this) {
11219                            mDidUpdate = true;
11220                        }
11221                        writeLastDonePreBootReceivers(doneReceivers);
11222                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11223                                false);
11224                        systemReady(goingCallback);
11225                    }
11226                }, doneReceivers, UserHandle.USER_OWNER);
11227
11228                if (mWaitingUpdate) {
11229                    return;
11230                }
11231                mDidUpdate = true;
11232            }
11233
11234            mAppOpsService.systemReady();
11235            mSystemReady = true;
11236        }
11237
11238        ArrayList<ProcessRecord> procsToKill = null;
11239        synchronized(mPidsSelfLocked) {
11240            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11241                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11242                if (!isAllowedWhileBooting(proc.info)){
11243                    if (procsToKill == null) {
11244                        procsToKill = new ArrayList<ProcessRecord>();
11245                    }
11246                    procsToKill.add(proc);
11247                }
11248            }
11249        }
11250
11251        synchronized(this) {
11252            if (procsToKill != null) {
11253                for (int i=procsToKill.size()-1; i>=0; i--) {
11254                    ProcessRecord proc = procsToKill.get(i);
11255                    Slog.i(TAG, "Removing system update proc: " + proc);
11256                    removeProcessLocked(proc, true, false, "system update done");
11257                }
11258            }
11259
11260            // Now that we have cleaned up any update processes, we
11261            // are ready to start launching real processes and know that
11262            // we won't trample on them any more.
11263            mProcessesReady = true;
11264        }
11265
11266        Slog.i(TAG, "System now ready");
11267        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11268            SystemClock.uptimeMillis());
11269
11270        synchronized(this) {
11271            // Make sure we have no pre-ready processes sitting around.
11272
11273            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11274                ResolveInfo ri = mContext.getPackageManager()
11275                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11276                                STOCK_PM_FLAGS);
11277                CharSequence errorMsg = null;
11278                if (ri != null) {
11279                    ActivityInfo ai = ri.activityInfo;
11280                    ApplicationInfo app = ai.applicationInfo;
11281                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11282                        mTopAction = Intent.ACTION_FACTORY_TEST;
11283                        mTopData = null;
11284                        mTopComponent = new ComponentName(app.packageName,
11285                                ai.name);
11286                    } else {
11287                        errorMsg = mContext.getResources().getText(
11288                                com.android.internal.R.string.factorytest_not_system);
11289                    }
11290                } else {
11291                    errorMsg = mContext.getResources().getText(
11292                            com.android.internal.R.string.factorytest_no_action);
11293                }
11294                if (errorMsg != null) {
11295                    mTopAction = null;
11296                    mTopData = null;
11297                    mTopComponent = null;
11298                    Message msg = Message.obtain();
11299                    msg.what = SHOW_FACTORY_ERROR_MSG;
11300                    msg.getData().putCharSequence("msg", errorMsg);
11301                    mHandler.sendMessage(msg);
11302                }
11303            }
11304        }
11305
11306        retrieveSettings();
11307        loadResourcesOnSystemReady();
11308
11309        synchronized (this) {
11310            readGrantedUriPermissionsLocked();
11311        }
11312
11313        if (goingCallback != null) goingCallback.run();
11314
11315        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11316                Integer.toString(mCurrentUserId), mCurrentUserId);
11317        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11318                Integer.toString(mCurrentUserId), mCurrentUserId);
11319        mSystemServiceManager.startUser(mCurrentUserId);
11320
11321        synchronized (this) {
11322            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11323                try {
11324                    List apps = AppGlobals.getPackageManager().
11325                        getPersistentApplications(STOCK_PM_FLAGS);
11326                    if (apps != null) {
11327                        int N = apps.size();
11328                        int i;
11329                        for (i=0; i<N; i++) {
11330                            ApplicationInfo info
11331                                = (ApplicationInfo)apps.get(i);
11332                            if (info != null &&
11333                                    !info.packageName.equals("android")) {
11334                                addAppLocked(info, false, null /* ABI override */);
11335                            }
11336                        }
11337                    }
11338                } catch (RemoteException ex) {
11339                    // pm is in same process, this will never happen.
11340                }
11341            }
11342
11343            // Start up initial activity.
11344            mBooting = true;
11345            startHomeActivityLocked(mCurrentUserId);
11346
11347            try {
11348                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11349                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11350                            + " data partition or your device will be unstable.");
11351                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11352                }
11353            } catch (RemoteException e) {
11354            }
11355
11356            if (!Build.isFingerprintConsistent()) {
11357                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11358                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11359            }
11360
11361            long ident = Binder.clearCallingIdentity();
11362            try {
11363                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11364                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11365                        | Intent.FLAG_RECEIVER_FOREGROUND);
11366                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11367                broadcastIntentLocked(null, null, intent,
11368                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11369                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11370                intent = new Intent(Intent.ACTION_USER_STARTING);
11371                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11372                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11373                broadcastIntentLocked(null, null, intent,
11374                        null, new IIntentReceiver.Stub() {
11375                            @Override
11376                            public void performReceive(Intent intent, int resultCode, String data,
11377                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11378                                    throws RemoteException {
11379                            }
11380                        }, 0, null, null,
11381                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11382                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11383            } catch (Throwable t) {
11384                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11385            } finally {
11386                Binder.restoreCallingIdentity(ident);
11387            }
11388            mStackSupervisor.resumeTopActivitiesLocked();
11389            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11390        }
11391    }
11392
11393    private boolean makeAppCrashingLocked(ProcessRecord app,
11394            String shortMsg, String longMsg, String stackTrace) {
11395        app.crashing = true;
11396        app.crashingReport = generateProcessError(app,
11397                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11398        startAppProblemLocked(app);
11399        app.stopFreezingAllLocked();
11400        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11401    }
11402
11403    private void makeAppNotRespondingLocked(ProcessRecord app,
11404            String activity, String shortMsg, String longMsg) {
11405        app.notResponding = true;
11406        app.notRespondingReport = generateProcessError(app,
11407                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11408                activity, shortMsg, longMsg, null);
11409        startAppProblemLocked(app);
11410        app.stopFreezingAllLocked();
11411    }
11412
11413    /**
11414     * Generate a process error record, suitable for attachment to a ProcessRecord.
11415     *
11416     * @param app The ProcessRecord in which the error occurred.
11417     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11418     *                      ActivityManager.AppErrorStateInfo
11419     * @param activity The activity associated with the crash, if known.
11420     * @param shortMsg Short message describing the crash.
11421     * @param longMsg Long message describing the crash.
11422     * @param stackTrace Full crash stack trace, may be null.
11423     *
11424     * @return Returns a fully-formed AppErrorStateInfo record.
11425     */
11426    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11427            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11428        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11429
11430        report.condition = condition;
11431        report.processName = app.processName;
11432        report.pid = app.pid;
11433        report.uid = app.info.uid;
11434        report.tag = activity;
11435        report.shortMsg = shortMsg;
11436        report.longMsg = longMsg;
11437        report.stackTrace = stackTrace;
11438
11439        return report;
11440    }
11441
11442    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11443        synchronized (this) {
11444            app.crashing = false;
11445            app.crashingReport = null;
11446            app.notResponding = false;
11447            app.notRespondingReport = null;
11448            if (app.anrDialog == fromDialog) {
11449                app.anrDialog = null;
11450            }
11451            if (app.waitDialog == fromDialog) {
11452                app.waitDialog = null;
11453            }
11454            if (app.pid > 0 && app.pid != MY_PID) {
11455                handleAppCrashLocked(app, null, null, null);
11456                app.kill("user request after error", true);
11457            }
11458        }
11459    }
11460
11461    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11462            String stackTrace) {
11463        long now = SystemClock.uptimeMillis();
11464
11465        Long crashTime;
11466        if (!app.isolated) {
11467            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11468        } else {
11469            crashTime = null;
11470        }
11471        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11472            // This process loses!
11473            Slog.w(TAG, "Process " + app.info.processName
11474                    + " has crashed too many times: killing!");
11475            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11476                    app.userId, app.info.processName, app.uid);
11477            mStackSupervisor.handleAppCrashLocked(app);
11478            if (!app.persistent) {
11479                // We don't want to start this process again until the user
11480                // explicitly does so...  but for persistent process, we really
11481                // need to keep it running.  If a persistent process is actually
11482                // repeatedly crashing, then badness for everyone.
11483                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11484                        app.info.processName);
11485                if (!app.isolated) {
11486                    // XXX We don't have a way to mark isolated processes
11487                    // as bad, since they don't have a peristent identity.
11488                    mBadProcesses.put(app.info.processName, app.uid,
11489                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11490                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11491                }
11492                app.bad = true;
11493                app.removed = true;
11494                // Don't let services in this process be restarted and potentially
11495                // annoy the user repeatedly.  Unless it is persistent, since those
11496                // processes run critical code.
11497                removeProcessLocked(app, false, false, "crash");
11498                mStackSupervisor.resumeTopActivitiesLocked();
11499                return false;
11500            }
11501            mStackSupervisor.resumeTopActivitiesLocked();
11502        } else {
11503            mStackSupervisor.finishTopRunningActivityLocked(app);
11504        }
11505
11506        // Bump up the crash count of any services currently running in the proc.
11507        for (int i=app.services.size()-1; i>=0; i--) {
11508            // Any services running in the application need to be placed
11509            // back in the pending list.
11510            ServiceRecord sr = app.services.valueAt(i);
11511            sr.crashCount++;
11512        }
11513
11514        // If the crashing process is what we consider to be the "home process" and it has been
11515        // replaced by a third-party app, clear the package preferred activities from packages
11516        // with a home activity running in the process to prevent a repeatedly crashing app
11517        // from blocking the user to manually clear the list.
11518        final ArrayList<ActivityRecord> activities = app.activities;
11519        if (app == mHomeProcess && activities.size() > 0
11520                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11521            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11522                final ActivityRecord r = activities.get(activityNdx);
11523                if (r.isHomeActivity()) {
11524                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11525                    try {
11526                        ActivityThread.getPackageManager()
11527                                .clearPackagePreferredActivities(r.packageName);
11528                    } catch (RemoteException c) {
11529                        // pm is in same process, this will never happen.
11530                    }
11531                }
11532            }
11533        }
11534
11535        if (!app.isolated) {
11536            // XXX Can't keep track of crash times for isolated processes,
11537            // because they don't have a perisistent identity.
11538            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11539        }
11540
11541        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11542        return true;
11543    }
11544
11545    void startAppProblemLocked(ProcessRecord app) {
11546        // If this app is not running under the current user, then we
11547        // can't give it a report button because that would require
11548        // launching the report UI under a different user.
11549        app.errorReportReceiver = null;
11550
11551        for (int userId : mCurrentProfileIds) {
11552            if (app.userId == userId) {
11553                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11554                        mContext, app.info.packageName, app.info.flags);
11555            }
11556        }
11557        skipCurrentReceiverLocked(app);
11558    }
11559
11560    void skipCurrentReceiverLocked(ProcessRecord app) {
11561        for (BroadcastQueue queue : mBroadcastQueues) {
11562            queue.skipCurrentReceiverLocked(app);
11563        }
11564    }
11565
11566    /**
11567     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11568     * The application process will exit immediately after this call returns.
11569     * @param app object of the crashing app, null for the system server
11570     * @param crashInfo describing the exception
11571     */
11572    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11573        ProcessRecord r = findAppProcess(app, "Crash");
11574        final String processName = app == null ? "system_server"
11575                : (r == null ? "unknown" : r.processName);
11576
11577        handleApplicationCrashInner("crash", r, processName, crashInfo);
11578    }
11579
11580    /* Native crash reporting uses this inner version because it needs to be somewhat
11581     * decoupled from the AM-managed cleanup lifecycle
11582     */
11583    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11584            ApplicationErrorReport.CrashInfo crashInfo) {
11585        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11586                UserHandle.getUserId(Binder.getCallingUid()), processName,
11587                r == null ? -1 : r.info.flags,
11588                crashInfo.exceptionClassName,
11589                crashInfo.exceptionMessage,
11590                crashInfo.throwFileName,
11591                crashInfo.throwLineNumber);
11592
11593        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11594
11595        crashApplication(r, crashInfo);
11596    }
11597
11598    public void handleApplicationStrictModeViolation(
11599            IBinder app,
11600            int violationMask,
11601            StrictMode.ViolationInfo info) {
11602        ProcessRecord r = findAppProcess(app, "StrictMode");
11603        if (r == null) {
11604            return;
11605        }
11606
11607        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11608            Integer stackFingerprint = info.hashCode();
11609            boolean logIt = true;
11610            synchronized (mAlreadyLoggedViolatedStacks) {
11611                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11612                    logIt = false;
11613                    // TODO: sub-sample into EventLog for these, with
11614                    // the info.durationMillis?  Then we'd get
11615                    // the relative pain numbers, without logging all
11616                    // the stack traces repeatedly.  We'd want to do
11617                    // likewise in the client code, which also does
11618                    // dup suppression, before the Binder call.
11619                } else {
11620                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11621                        mAlreadyLoggedViolatedStacks.clear();
11622                    }
11623                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11624                }
11625            }
11626            if (logIt) {
11627                logStrictModeViolationToDropBox(r, info);
11628            }
11629        }
11630
11631        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11632            AppErrorResult result = new AppErrorResult();
11633            synchronized (this) {
11634                final long origId = Binder.clearCallingIdentity();
11635
11636                Message msg = Message.obtain();
11637                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11638                HashMap<String, Object> data = new HashMap<String, Object>();
11639                data.put("result", result);
11640                data.put("app", r);
11641                data.put("violationMask", violationMask);
11642                data.put("info", info);
11643                msg.obj = data;
11644                mHandler.sendMessage(msg);
11645
11646                Binder.restoreCallingIdentity(origId);
11647            }
11648            int res = result.get();
11649            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11650        }
11651    }
11652
11653    // Depending on the policy in effect, there could be a bunch of
11654    // these in quick succession so we try to batch these together to
11655    // minimize disk writes, number of dropbox entries, and maximize
11656    // compression, by having more fewer, larger records.
11657    private void logStrictModeViolationToDropBox(
11658            ProcessRecord process,
11659            StrictMode.ViolationInfo info) {
11660        if (info == null) {
11661            return;
11662        }
11663        final boolean isSystemApp = process == null ||
11664                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11665                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11666        final String processName = process == null ? "unknown" : process.processName;
11667        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11668        final DropBoxManager dbox = (DropBoxManager)
11669                mContext.getSystemService(Context.DROPBOX_SERVICE);
11670
11671        // Exit early if the dropbox isn't configured to accept this report type.
11672        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11673
11674        boolean bufferWasEmpty;
11675        boolean needsFlush;
11676        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11677        synchronized (sb) {
11678            bufferWasEmpty = sb.length() == 0;
11679            appendDropBoxProcessHeaders(process, processName, sb);
11680            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11681            sb.append("System-App: ").append(isSystemApp).append("\n");
11682            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11683            if (info.violationNumThisLoop != 0) {
11684                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11685            }
11686            if (info.numAnimationsRunning != 0) {
11687                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11688            }
11689            if (info.broadcastIntentAction != null) {
11690                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11691            }
11692            if (info.durationMillis != -1) {
11693                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11694            }
11695            if (info.numInstances != -1) {
11696                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11697            }
11698            if (info.tags != null) {
11699                for (String tag : info.tags) {
11700                    sb.append("Span-Tag: ").append(tag).append("\n");
11701                }
11702            }
11703            sb.append("\n");
11704            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11705                sb.append(info.crashInfo.stackTrace);
11706            }
11707            sb.append("\n");
11708
11709            // Only buffer up to ~64k.  Various logging bits truncate
11710            // things at 128k.
11711            needsFlush = (sb.length() > 64 * 1024);
11712        }
11713
11714        // Flush immediately if the buffer's grown too large, or this
11715        // is a non-system app.  Non-system apps are isolated with a
11716        // different tag & policy and not batched.
11717        //
11718        // Batching is useful during internal testing with
11719        // StrictMode settings turned up high.  Without batching,
11720        // thousands of separate files could be created on boot.
11721        if (!isSystemApp || needsFlush) {
11722            new Thread("Error dump: " + dropboxTag) {
11723                @Override
11724                public void run() {
11725                    String report;
11726                    synchronized (sb) {
11727                        report = sb.toString();
11728                        sb.delete(0, sb.length());
11729                        sb.trimToSize();
11730                    }
11731                    if (report.length() != 0) {
11732                        dbox.addText(dropboxTag, report);
11733                    }
11734                }
11735            }.start();
11736            return;
11737        }
11738
11739        // System app batching:
11740        if (!bufferWasEmpty) {
11741            // An existing dropbox-writing thread is outstanding, so
11742            // we don't need to start it up.  The existing thread will
11743            // catch the buffer appends we just did.
11744            return;
11745        }
11746
11747        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11748        // (After this point, we shouldn't access AMS internal data structures.)
11749        new Thread("Error dump: " + dropboxTag) {
11750            @Override
11751            public void run() {
11752                // 5 second sleep to let stacks arrive and be batched together
11753                try {
11754                    Thread.sleep(5000);  // 5 seconds
11755                } catch (InterruptedException e) {}
11756
11757                String errorReport;
11758                synchronized (mStrictModeBuffer) {
11759                    errorReport = mStrictModeBuffer.toString();
11760                    if (errorReport.length() == 0) {
11761                        return;
11762                    }
11763                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11764                    mStrictModeBuffer.trimToSize();
11765                }
11766                dbox.addText(dropboxTag, errorReport);
11767            }
11768        }.start();
11769    }
11770
11771    /**
11772     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11773     * @param app object of the crashing app, null for the system server
11774     * @param tag reported by the caller
11775     * @param system whether this wtf is coming from the system
11776     * @param crashInfo describing the context of the error
11777     * @return true if the process should exit immediately (WTF is fatal)
11778     */
11779    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11780            final ApplicationErrorReport.CrashInfo crashInfo) {
11781        final int callingUid = Binder.getCallingUid();
11782        final int callingPid = Binder.getCallingPid();
11783
11784        if (system) {
11785            // If this is coming from the system, we could very well have low-level
11786            // system locks held, so we want to do this all asynchronously.  And we
11787            // never want this to become fatal, so there is that too.
11788            mHandler.post(new Runnable() {
11789                @Override public void run() {
11790                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11791                }
11792            });
11793            return false;
11794        }
11795
11796        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11797                crashInfo);
11798
11799        if (r != null && r.pid != Process.myPid() &&
11800                Settings.Global.getInt(mContext.getContentResolver(),
11801                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11802            crashApplication(r, crashInfo);
11803            return true;
11804        } else {
11805            return false;
11806        }
11807    }
11808
11809    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11810            final ApplicationErrorReport.CrashInfo crashInfo) {
11811        final ProcessRecord r = findAppProcess(app, "WTF");
11812        final String processName = app == null ? "system_server"
11813                : (r == null ? "unknown" : r.processName);
11814
11815        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11816                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11817
11818        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11819
11820        return r;
11821    }
11822
11823    /**
11824     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11825     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11826     */
11827    private ProcessRecord findAppProcess(IBinder app, String reason) {
11828        if (app == null) {
11829            return null;
11830        }
11831
11832        synchronized (this) {
11833            final int NP = mProcessNames.getMap().size();
11834            for (int ip=0; ip<NP; ip++) {
11835                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11836                final int NA = apps.size();
11837                for (int ia=0; ia<NA; ia++) {
11838                    ProcessRecord p = apps.valueAt(ia);
11839                    if (p.thread != null && p.thread.asBinder() == app) {
11840                        return p;
11841                    }
11842                }
11843            }
11844
11845            Slog.w(TAG, "Can't find mystery application for " + reason
11846                    + " from pid=" + Binder.getCallingPid()
11847                    + " uid=" + Binder.getCallingUid() + ": " + app);
11848            return null;
11849        }
11850    }
11851
11852    /**
11853     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11854     * to append various headers to the dropbox log text.
11855     */
11856    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11857            StringBuilder sb) {
11858        // Watchdog thread ends up invoking this function (with
11859        // a null ProcessRecord) to add the stack file to dropbox.
11860        // Do not acquire a lock on this (am) in such cases, as it
11861        // could cause a potential deadlock, if and when watchdog
11862        // is invoked due to unavailability of lock on am and it
11863        // would prevent watchdog from killing system_server.
11864        if (process == null) {
11865            sb.append("Process: ").append(processName).append("\n");
11866            return;
11867        }
11868        // Note: ProcessRecord 'process' is guarded by the service
11869        // instance.  (notably process.pkgList, which could otherwise change
11870        // concurrently during execution of this method)
11871        synchronized (this) {
11872            sb.append("Process: ").append(processName).append("\n");
11873            int flags = process.info.flags;
11874            IPackageManager pm = AppGlobals.getPackageManager();
11875            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11876            for (int ip=0; ip<process.pkgList.size(); ip++) {
11877                String pkg = process.pkgList.keyAt(ip);
11878                sb.append("Package: ").append(pkg);
11879                try {
11880                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11881                    if (pi != null) {
11882                        sb.append(" v").append(pi.versionCode);
11883                        if (pi.versionName != null) {
11884                            sb.append(" (").append(pi.versionName).append(")");
11885                        }
11886                    }
11887                } catch (RemoteException e) {
11888                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11889                }
11890                sb.append("\n");
11891            }
11892        }
11893    }
11894
11895    private static String processClass(ProcessRecord process) {
11896        if (process == null || process.pid == MY_PID) {
11897            return "system_server";
11898        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11899            return "system_app";
11900        } else {
11901            return "data_app";
11902        }
11903    }
11904
11905    /**
11906     * Write a description of an error (crash, WTF, ANR) to the drop box.
11907     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11908     * @param process which caused the error, null means the system server
11909     * @param activity which triggered the error, null if unknown
11910     * @param parent activity related to the error, null if unknown
11911     * @param subject line related to the error, null if absent
11912     * @param report in long form describing the error, null if absent
11913     * @param logFile to include in the report, null if none
11914     * @param crashInfo giving an application stack trace, null if absent
11915     */
11916    public void addErrorToDropBox(String eventType,
11917            ProcessRecord process, String processName, ActivityRecord activity,
11918            ActivityRecord parent, String subject,
11919            final String report, final File logFile,
11920            final ApplicationErrorReport.CrashInfo crashInfo) {
11921        // NOTE -- this must never acquire the ActivityManagerService lock,
11922        // otherwise the watchdog may be prevented from resetting the system.
11923
11924        final String dropboxTag = processClass(process) + "_" + eventType;
11925        final DropBoxManager dbox = (DropBoxManager)
11926                mContext.getSystemService(Context.DROPBOX_SERVICE);
11927
11928        // Exit early if the dropbox isn't configured to accept this report type.
11929        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11930
11931        final StringBuilder sb = new StringBuilder(1024);
11932        appendDropBoxProcessHeaders(process, processName, sb);
11933        if (activity != null) {
11934            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11935        }
11936        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11937            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11938        }
11939        if (parent != null && parent != activity) {
11940            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11941        }
11942        if (subject != null) {
11943            sb.append("Subject: ").append(subject).append("\n");
11944        }
11945        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11946        if (Debug.isDebuggerConnected()) {
11947            sb.append("Debugger: Connected\n");
11948        }
11949        sb.append("\n");
11950
11951        // Do the rest in a worker thread to avoid blocking the caller on I/O
11952        // (After this point, we shouldn't access AMS internal data structures.)
11953        Thread worker = new Thread("Error dump: " + dropboxTag) {
11954            @Override
11955            public void run() {
11956                if (report != null) {
11957                    sb.append(report);
11958                }
11959                if (logFile != null) {
11960                    try {
11961                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11962                                    "\n\n[[TRUNCATED]]"));
11963                    } catch (IOException e) {
11964                        Slog.e(TAG, "Error reading " + logFile, e);
11965                    }
11966                }
11967                if (crashInfo != null && crashInfo.stackTrace != null) {
11968                    sb.append(crashInfo.stackTrace);
11969                }
11970
11971                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11972                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11973                if (lines > 0) {
11974                    sb.append("\n");
11975
11976                    // Merge several logcat streams, and take the last N lines
11977                    InputStreamReader input = null;
11978                    try {
11979                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11980                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11981                                "-b", "crash",
11982                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11983
11984                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11985                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11986                        input = new InputStreamReader(logcat.getInputStream());
11987
11988                        int num;
11989                        char[] buf = new char[8192];
11990                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11991                    } catch (IOException e) {
11992                        Slog.e(TAG, "Error running logcat", e);
11993                    } finally {
11994                        if (input != null) try { input.close(); } catch (IOException e) {}
11995                    }
11996                }
11997
11998                dbox.addText(dropboxTag, sb.toString());
11999            }
12000        };
12001
12002        if (process == null) {
12003            // If process is null, we are being called from some internal code
12004            // and may be about to die -- run this synchronously.
12005            worker.run();
12006        } else {
12007            worker.start();
12008        }
12009    }
12010
12011    /**
12012     * Bring up the "unexpected error" dialog box for a crashing app.
12013     * Deal with edge cases (intercepts from instrumented applications,
12014     * ActivityController, error intent receivers, that sort of thing).
12015     * @param r the application crashing
12016     * @param crashInfo describing the failure
12017     */
12018    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12019        long timeMillis = System.currentTimeMillis();
12020        String shortMsg = crashInfo.exceptionClassName;
12021        String longMsg = crashInfo.exceptionMessage;
12022        String stackTrace = crashInfo.stackTrace;
12023        if (shortMsg != null && longMsg != null) {
12024            longMsg = shortMsg + ": " + longMsg;
12025        } else if (shortMsg != null) {
12026            longMsg = shortMsg;
12027        }
12028
12029        AppErrorResult result = new AppErrorResult();
12030        synchronized (this) {
12031            if (mController != null) {
12032                try {
12033                    String name = r != null ? r.processName : null;
12034                    int pid = r != null ? r.pid : Binder.getCallingPid();
12035                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12036                    if (!mController.appCrashed(name, pid,
12037                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12038                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12039                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12040                            Slog.w(TAG, "Skip killing native crashed app " + name
12041                                    + "(" + pid + ") during testing");
12042                        } else {
12043                            Slog.w(TAG, "Force-killing crashed app " + name
12044                                    + " at watcher's request");
12045                            if (r != null) {
12046                                r.kill("crash", true);
12047                            } else {
12048                                // Huh.
12049                                Process.killProcess(pid);
12050                                Process.killProcessGroup(uid, pid);
12051                            }
12052                        }
12053                        return;
12054                    }
12055                } catch (RemoteException e) {
12056                    mController = null;
12057                    Watchdog.getInstance().setActivityController(null);
12058                }
12059            }
12060
12061            final long origId = Binder.clearCallingIdentity();
12062
12063            // If this process is running instrumentation, finish it.
12064            if (r != null && r.instrumentationClass != null) {
12065                Slog.w(TAG, "Error in app " + r.processName
12066                      + " running instrumentation " + r.instrumentationClass + ":");
12067                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12068                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12069                Bundle info = new Bundle();
12070                info.putString("shortMsg", shortMsg);
12071                info.putString("longMsg", longMsg);
12072                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12073                Binder.restoreCallingIdentity(origId);
12074                return;
12075            }
12076
12077            // Log crash in battery stats.
12078            if (r != null) {
12079                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12080            }
12081
12082            // If we can't identify the process or it's already exceeded its crash quota,
12083            // quit right away without showing a crash dialog.
12084            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12085                Binder.restoreCallingIdentity(origId);
12086                return;
12087            }
12088
12089            Message msg = Message.obtain();
12090            msg.what = SHOW_ERROR_MSG;
12091            HashMap data = new HashMap();
12092            data.put("result", result);
12093            data.put("app", r);
12094            msg.obj = data;
12095            mHandler.sendMessage(msg);
12096
12097            Binder.restoreCallingIdentity(origId);
12098        }
12099
12100        int res = result.get();
12101
12102        Intent appErrorIntent = null;
12103        synchronized (this) {
12104            if (r != null && !r.isolated) {
12105                // XXX Can't keep track of crash time for isolated processes,
12106                // since they don't have a persistent identity.
12107                mProcessCrashTimes.put(r.info.processName, r.uid,
12108                        SystemClock.uptimeMillis());
12109            }
12110            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12111                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12112            }
12113        }
12114
12115        if (appErrorIntent != null) {
12116            try {
12117                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12118            } catch (ActivityNotFoundException e) {
12119                Slog.w(TAG, "bug report receiver dissappeared", e);
12120            }
12121        }
12122    }
12123
12124    Intent createAppErrorIntentLocked(ProcessRecord r,
12125            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12126        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12127        if (report == null) {
12128            return null;
12129        }
12130        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12131        result.setComponent(r.errorReportReceiver);
12132        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12133        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12134        return result;
12135    }
12136
12137    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12138            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12139        if (r.errorReportReceiver == null) {
12140            return null;
12141        }
12142
12143        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12144            return null;
12145        }
12146
12147        ApplicationErrorReport report = new ApplicationErrorReport();
12148        report.packageName = r.info.packageName;
12149        report.installerPackageName = r.errorReportReceiver.getPackageName();
12150        report.processName = r.processName;
12151        report.time = timeMillis;
12152        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12153
12154        if (r.crashing || r.forceCrashReport) {
12155            report.type = ApplicationErrorReport.TYPE_CRASH;
12156            report.crashInfo = crashInfo;
12157        } else if (r.notResponding) {
12158            report.type = ApplicationErrorReport.TYPE_ANR;
12159            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12160
12161            report.anrInfo.activity = r.notRespondingReport.tag;
12162            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12163            report.anrInfo.info = r.notRespondingReport.longMsg;
12164        }
12165
12166        return report;
12167    }
12168
12169    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12170        enforceNotIsolatedCaller("getProcessesInErrorState");
12171        // assume our apps are happy - lazy create the list
12172        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12173
12174        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12175                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12176        int userId = UserHandle.getUserId(Binder.getCallingUid());
12177
12178        synchronized (this) {
12179
12180            // iterate across all processes
12181            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12182                ProcessRecord app = mLruProcesses.get(i);
12183                if (!allUsers && app.userId != userId) {
12184                    continue;
12185                }
12186                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12187                    // This one's in trouble, so we'll generate a report for it
12188                    // crashes are higher priority (in case there's a crash *and* an anr)
12189                    ActivityManager.ProcessErrorStateInfo report = null;
12190                    if (app.crashing) {
12191                        report = app.crashingReport;
12192                    } else if (app.notResponding) {
12193                        report = app.notRespondingReport;
12194                    }
12195
12196                    if (report != null) {
12197                        if (errList == null) {
12198                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12199                        }
12200                        errList.add(report);
12201                    } else {
12202                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12203                                " crashing = " + app.crashing +
12204                                " notResponding = " + app.notResponding);
12205                    }
12206                }
12207            }
12208        }
12209
12210        return errList;
12211    }
12212
12213    static int procStateToImportance(int procState, int memAdj,
12214            ActivityManager.RunningAppProcessInfo currApp) {
12215        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12216        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12217            currApp.lru = memAdj;
12218        } else {
12219            currApp.lru = 0;
12220        }
12221        return imp;
12222    }
12223
12224    private void fillInProcMemInfo(ProcessRecord app,
12225            ActivityManager.RunningAppProcessInfo outInfo) {
12226        outInfo.pid = app.pid;
12227        outInfo.uid = app.info.uid;
12228        if (mHeavyWeightProcess == app) {
12229            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12230        }
12231        if (app.persistent) {
12232            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12233        }
12234        if (app.activities.size() > 0) {
12235            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12236        }
12237        outInfo.lastTrimLevel = app.trimMemoryLevel;
12238        int adj = app.curAdj;
12239        int procState = app.curProcState;
12240        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12241        outInfo.importanceReasonCode = app.adjTypeCode;
12242        outInfo.processState = app.curProcState;
12243    }
12244
12245    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12246        enforceNotIsolatedCaller("getRunningAppProcesses");
12247        // Lazy instantiation of list
12248        List<ActivityManager.RunningAppProcessInfo> runList = null;
12249        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12250                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12251        int userId = UserHandle.getUserId(Binder.getCallingUid());
12252        synchronized (this) {
12253            // Iterate across all processes
12254            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12255                ProcessRecord app = mLruProcesses.get(i);
12256                if (!allUsers && app.userId != userId) {
12257                    continue;
12258                }
12259                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12260                    // Generate process state info for running application
12261                    ActivityManager.RunningAppProcessInfo currApp =
12262                        new ActivityManager.RunningAppProcessInfo(app.processName,
12263                                app.pid, app.getPackageList());
12264                    fillInProcMemInfo(app, currApp);
12265                    if (app.adjSource instanceof ProcessRecord) {
12266                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12267                        currApp.importanceReasonImportance =
12268                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12269                                        app.adjSourceProcState);
12270                    } else if (app.adjSource instanceof ActivityRecord) {
12271                        ActivityRecord r = (ActivityRecord)app.adjSource;
12272                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12273                    }
12274                    if (app.adjTarget instanceof ComponentName) {
12275                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12276                    }
12277                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12278                    //        + " lru=" + currApp.lru);
12279                    if (runList == null) {
12280                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12281                    }
12282                    runList.add(currApp);
12283                }
12284            }
12285        }
12286        return runList;
12287    }
12288
12289    public List<ApplicationInfo> getRunningExternalApplications() {
12290        enforceNotIsolatedCaller("getRunningExternalApplications");
12291        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12292        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12293        if (runningApps != null && runningApps.size() > 0) {
12294            Set<String> extList = new HashSet<String>();
12295            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12296                if (app.pkgList != null) {
12297                    for (String pkg : app.pkgList) {
12298                        extList.add(pkg);
12299                    }
12300                }
12301            }
12302            IPackageManager pm = AppGlobals.getPackageManager();
12303            for (String pkg : extList) {
12304                try {
12305                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12306                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12307                        retList.add(info);
12308                    }
12309                } catch (RemoteException e) {
12310                }
12311            }
12312        }
12313        return retList;
12314    }
12315
12316    @Override
12317    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12318        enforceNotIsolatedCaller("getMyMemoryState");
12319        synchronized (this) {
12320            ProcessRecord proc;
12321            synchronized (mPidsSelfLocked) {
12322                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12323            }
12324            fillInProcMemInfo(proc, outInfo);
12325        }
12326    }
12327
12328    @Override
12329    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12330        if (checkCallingPermission(android.Manifest.permission.DUMP)
12331                != PackageManager.PERMISSION_GRANTED) {
12332            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12333                    + Binder.getCallingPid()
12334                    + ", uid=" + Binder.getCallingUid()
12335                    + " without permission "
12336                    + android.Manifest.permission.DUMP);
12337            return;
12338        }
12339
12340        boolean dumpAll = false;
12341        boolean dumpClient = false;
12342        String dumpPackage = null;
12343
12344        int opti = 0;
12345        while (opti < args.length) {
12346            String opt = args[opti];
12347            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12348                break;
12349            }
12350            opti++;
12351            if ("-a".equals(opt)) {
12352                dumpAll = true;
12353            } else if ("-c".equals(opt)) {
12354                dumpClient = true;
12355            } else if ("-p".equals(opt)) {
12356                if (opti < args.length) {
12357                    dumpPackage = args[opti];
12358                    opti++;
12359                } else {
12360                    pw.println("Error: -p option requires package argument");
12361                    return;
12362                }
12363                dumpClient = true;
12364            } else if ("-h".equals(opt)) {
12365                pw.println("Activity manager dump options:");
12366                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12367                pw.println("  cmd may be one of:");
12368                pw.println("    a[ctivities]: activity stack state");
12369                pw.println("    r[recents]: recent activities state");
12370                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12371                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12372                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12373                pw.println("    o[om]: out of memory management");
12374                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12375                pw.println("    provider [COMP_SPEC]: provider client-side state");
12376                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12377                pw.println("    as[sociations]: tracked app associations");
12378                pw.println("    service [COMP_SPEC]: service client-side state");
12379                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12380                pw.println("    all: dump all activities");
12381                pw.println("    top: dump the top activity");
12382                pw.println("    write: write all pending state to storage");
12383                pw.println("    track-associations: enable association tracking");
12384                pw.println("    untrack-associations: disable and clear association tracking");
12385                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12386                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12387                pw.println("    a partial substring in a component name, a");
12388                pw.println("    hex object identifier.");
12389                pw.println("  -a: include all available server state.");
12390                pw.println("  -c: include client state.");
12391                pw.println("  -p: limit output to given package.");
12392                return;
12393            } else {
12394                pw.println("Unknown argument: " + opt + "; use -h for help");
12395            }
12396        }
12397
12398        long origId = Binder.clearCallingIdentity();
12399        boolean more = false;
12400        // Is the caller requesting to dump a particular piece of data?
12401        if (opti < args.length) {
12402            String cmd = args[opti];
12403            opti++;
12404            if ("activities".equals(cmd) || "a".equals(cmd)) {
12405                synchronized (this) {
12406                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12407                }
12408            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12409                synchronized (this) {
12410                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12411                }
12412            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12413                String[] newArgs;
12414                String name;
12415                if (opti >= args.length) {
12416                    name = null;
12417                    newArgs = EMPTY_STRING_ARRAY;
12418                } else {
12419                    dumpPackage = args[opti];
12420                    opti++;
12421                    newArgs = new String[args.length - opti];
12422                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12423                            args.length - opti);
12424                }
12425                synchronized (this) {
12426                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12427                }
12428            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12429                String[] newArgs;
12430                String name;
12431                if (opti >= args.length) {
12432                    name = null;
12433                    newArgs = EMPTY_STRING_ARRAY;
12434                } else {
12435                    dumpPackage = args[opti];
12436                    opti++;
12437                    newArgs = new String[args.length - opti];
12438                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12439                            args.length - opti);
12440                }
12441                synchronized (this) {
12442                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12443                }
12444            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12445                String[] newArgs;
12446                String name;
12447                if (opti >= args.length) {
12448                    name = null;
12449                    newArgs = EMPTY_STRING_ARRAY;
12450                } else {
12451                    dumpPackage = args[opti];
12452                    opti++;
12453                    newArgs = new String[args.length - opti];
12454                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12455                            args.length - opti);
12456                }
12457                synchronized (this) {
12458                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12459                }
12460            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12461                synchronized (this) {
12462                    dumpOomLocked(fd, pw, args, opti, true);
12463                }
12464            } else if ("provider".equals(cmd)) {
12465                String[] newArgs;
12466                String name;
12467                if (opti >= args.length) {
12468                    name = null;
12469                    newArgs = EMPTY_STRING_ARRAY;
12470                } else {
12471                    name = args[opti];
12472                    opti++;
12473                    newArgs = new String[args.length - opti];
12474                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12475                }
12476                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12477                    pw.println("No providers match: " + name);
12478                    pw.println("Use -h for help.");
12479                }
12480            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12481                synchronized (this) {
12482                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12483                }
12484            } else if ("service".equals(cmd)) {
12485                String[] newArgs;
12486                String name;
12487                if (opti >= args.length) {
12488                    name = null;
12489                    newArgs = EMPTY_STRING_ARRAY;
12490                } else {
12491                    name = args[opti];
12492                    opti++;
12493                    newArgs = new String[args.length - opti];
12494                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12495                            args.length - opti);
12496                }
12497                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12498                    pw.println("No services match: " + name);
12499                    pw.println("Use -h for help.");
12500                }
12501            } else if ("package".equals(cmd)) {
12502                String[] newArgs;
12503                if (opti >= args.length) {
12504                    pw.println("package: no package name specified");
12505                    pw.println("Use -h for help.");
12506                } else {
12507                    dumpPackage = args[opti];
12508                    opti++;
12509                    newArgs = new String[args.length - opti];
12510                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12511                            args.length - opti);
12512                    args = newArgs;
12513                    opti = 0;
12514                    more = true;
12515                }
12516            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12517                synchronized (this) {
12518                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12519                }
12520            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12521                synchronized (this) {
12522                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12523                }
12524            } else if ("write".equals(cmd)) {
12525                mTaskPersister.flush();
12526                pw.println("All tasks persisted.");
12527                return;
12528            } else if ("track-associations".equals(cmd)) {
12529                synchronized (this) {
12530                    if (!mTrackingAssociations) {
12531                        mTrackingAssociations = true;
12532                        pw.println("Association tracking started.");
12533                    } else {
12534                        pw.println("Association tracking already enabled.");
12535                    }
12536                }
12537                return;
12538            } else if ("untrack-associations".equals(cmd)) {
12539                synchronized (this) {
12540                    if (mTrackingAssociations) {
12541                        mTrackingAssociations = false;
12542                        mAssociations.clear();
12543                        pw.println("Association tracking stopped.");
12544                    } else {
12545                        pw.println("Association tracking not running.");
12546                    }
12547                }
12548                return;
12549            } else {
12550                // Dumping a single activity?
12551                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12552                    pw.println("Bad activity command, or no activities match: " + cmd);
12553                    pw.println("Use -h for help.");
12554                }
12555            }
12556            if (!more) {
12557                Binder.restoreCallingIdentity(origId);
12558                return;
12559            }
12560        }
12561
12562        // No piece of data specified, dump everything.
12563        synchronized (this) {
12564            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12565            pw.println();
12566            if (dumpAll) {
12567                pw.println("-------------------------------------------------------------------------------");
12568            }
12569            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12570            pw.println();
12571            if (dumpAll) {
12572                pw.println("-------------------------------------------------------------------------------");
12573            }
12574            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12575            pw.println();
12576            if (dumpAll) {
12577                pw.println("-------------------------------------------------------------------------------");
12578            }
12579            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12580            pw.println();
12581            if (dumpAll) {
12582                pw.println("-------------------------------------------------------------------------------");
12583            }
12584            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12585            pw.println();
12586            if (dumpAll) {
12587                pw.println("-------------------------------------------------------------------------------");
12588            }
12589            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12590            if (mAssociations.size() > 0) {
12591                pw.println();
12592                if (dumpAll) {
12593                    pw.println("-------------------------------------------------------------------------------");
12594                }
12595                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12596            }
12597            pw.println();
12598            if (dumpAll) {
12599                pw.println("-------------------------------------------------------------------------------");
12600            }
12601            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12602        }
12603        Binder.restoreCallingIdentity(origId);
12604    }
12605
12606    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12607            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12608        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12609
12610        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12611                dumpPackage);
12612        boolean needSep = printedAnything;
12613
12614        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12615                dumpPackage, needSep, "  mFocusedActivity: ");
12616        if (printed) {
12617            printedAnything = true;
12618            needSep = false;
12619        }
12620
12621        if (dumpPackage == null) {
12622            if (needSep) {
12623                pw.println();
12624            }
12625            needSep = true;
12626            printedAnything = true;
12627            mStackSupervisor.dump(pw, "  ");
12628        }
12629
12630        if (!printedAnything) {
12631            pw.println("  (nothing)");
12632        }
12633    }
12634
12635    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12636            int opti, boolean dumpAll, String dumpPackage) {
12637        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12638
12639        boolean printedAnything = false;
12640
12641        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12642            boolean printedHeader = false;
12643
12644            final int N = mRecentTasks.size();
12645            for (int i=0; i<N; i++) {
12646                TaskRecord tr = mRecentTasks.get(i);
12647                if (dumpPackage != null) {
12648                    if (tr.realActivity == null ||
12649                            !dumpPackage.equals(tr.realActivity)) {
12650                        continue;
12651                    }
12652                }
12653                if (!printedHeader) {
12654                    pw.println("  Recent tasks:");
12655                    printedHeader = true;
12656                    printedAnything = true;
12657                }
12658                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12659                        pw.println(tr);
12660                if (dumpAll) {
12661                    mRecentTasks.get(i).dump(pw, "    ");
12662                }
12663            }
12664        }
12665
12666        if (!printedAnything) {
12667            pw.println("  (nothing)");
12668        }
12669    }
12670
12671    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12672            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12673        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12674
12675        int dumpUid = 0;
12676        if (dumpPackage != null) {
12677            IPackageManager pm = AppGlobals.getPackageManager();
12678            try {
12679                dumpUid = pm.getPackageUid(dumpPackage, 0);
12680            } catch (RemoteException e) {
12681            }
12682        }
12683
12684        boolean printedAnything = false;
12685
12686        final long now = SystemClock.uptimeMillis();
12687
12688        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12689            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12690                    = mAssociations.valueAt(i1);
12691            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12692                SparseArray<ArrayMap<String, Association>> sourceUids
12693                        = targetComponents.valueAt(i2);
12694                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12695                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12696                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12697                        Association ass = sourceProcesses.valueAt(i4);
12698                        if (dumpPackage != null) {
12699                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12700                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12701                                continue;
12702                            }
12703                        }
12704                        printedAnything = true;
12705                        pw.print("  ");
12706                        pw.print(ass.mTargetProcess);
12707                        pw.print("/");
12708                        UserHandle.formatUid(pw, ass.mTargetUid);
12709                        pw.print(" <- ");
12710                        pw.print(ass.mSourceProcess);
12711                        pw.print("/");
12712                        UserHandle.formatUid(pw, ass.mSourceUid);
12713                        pw.println();
12714                        pw.print("    via ");
12715                        pw.print(ass.mTargetComponent.flattenToShortString());
12716                        pw.println();
12717                        pw.print("    ");
12718                        long dur = ass.mTime;
12719                        if (ass.mNesting > 0) {
12720                            dur += now - ass.mStartTime;
12721                        }
12722                        TimeUtils.formatDuration(dur, pw);
12723                        pw.print(" (");
12724                        pw.print(ass.mCount);
12725                        pw.println(" times)");
12726                        if (ass.mNesting > 0) {
12727                            pw.print("    ");
12728                            pw.print(" Currently active: ");
12729                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12730                            pw.println();
12731                        }
12732                    }
12733                }
12734            }
12735
12736        }
12737
12738        if (!printedAnything) {
12739            pw.println("  (nothing)");
12740        }
12741    }
12742
12743    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12744            int opti, boolean dumpAll, String dumpPackage) {
12745        boolean needSep = false;
12746        boolean printedAnything = false;
12747        int numPers = 0;
12748
12749        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12750
12751        if (dumpAll) {
12752            final int NP = mProcessNames.getMap().size();
12753            for (int ip=0; ip<NP; ip++) {
12754                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12755                final int NA = procs.size();
12756                for (int ia=0; ia<NA; ia++) {
12757                    ProcessRecord r = procs.valueAt(ia);
12758                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12759                        continue;
12760                    }
12761                    if (!needSep) {
12762                        pw.println("  All known processes:");
12763                        needSep = true;
12764                        printedAnything = true;
12765                    }
12766                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12767                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12768                        pw.print(" "); pw.println(r);
12769                    r.dump(pw, "    ");
12770                    if (r.persistent) {
12771                        numPers++;
12772                    }
12773                }
12774            }
12775        }
12776
12777        if (mIsolatedProcesses.size() > 0) {
12778            boolean printed = false;
12779            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12780                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12781                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12782                    continue;
12783                }
12784                if (!printed) {
12785                    if (needSep) {
12786                        pw.println();
12787                    }
12788                    pw.println("  Isolated process list (sorted by uid):");
12789                    printedAnything = true;
12790                    printed = true;
12791                    needSep = true;
12792                }
12793                pw.println(String.format("%sIsolated #%2d: %s",
12794                        "    ", i, r.toString()));
12795            }
12796        }
12797
12798        if (mLruProcesses.size() > 0) {
12799            if (needSep) {
12800                pw.println();
12801            }
12802            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12803                    pw.print(" total, non-act at ");
12804                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12805                    pw.print(", non-svc at ");
12806                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12807                    pw.println("):");
12808            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12809            needSep = true;
12810            printedAnything = true;
12811        }
12812
12813        if (dumpAll || dumpPackage != null) {
12814            synchronized (mPidsSelfLocked) {
12815                boolean printed = false;
12816                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12817                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12818                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12819                        continue;
12820                    }
12821                    if (!printed) {
12822                        if (needSep) pw.println();
12823                        needSep = true;
12824                        pw.println("  PID mappings:");
12825                        printed = true;
12826                        printedAnything = true;
12827                    }
12828                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12829                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12830                }
12831            }
12832        }
12833
12834        if (mForegroundProcesses.size() > 0) {
12835            synchronized (mPidsSelfLocked) {
12836                boolean printed = false;
12837                for (int i=0; i<mForegroundProcesses.size(); i++) {
12838                    ProcessRecord r = mPidsSelfLocked.get(
12839                            mForegroundProcesses.valueAt(i).pid);
12840                    if (dumpPackage != null && (r == null
12841                            || !r.pkgList.containsKey(dumpPackage))) {
12842                        continue;
12843                    }
12844                    if (!printed) {
12845                        if (needSep) pw.println();
12846                        needSep = true;
12847                        pw.println("  Foreground Processes:");
12848                        printed = true;
12849                        printedAnything = true;
12850                    }
12851                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12852                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12853                }
12854            }
12855        }
12856
12857        if (mPersistentStartingProcesses.size() > 0) {
12858            if (needSep) pw.println();
12859            needSep = true;
12860            printedAnything = true;
12861            pw.println("  Persisent processes that are starting:");
12862            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12863                    "Starting Norm", "Restarting PERS", dumpPackage);
12864        }
12865
12866        if (mRemovedProcesses.size() > 0) {
12867            if (needSep) pw.println();
12868            needSep = true;
12869            printedAnything = true;
12870            pw.println("  Processes that are being removed:");
12871            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12872                    "Removed Norm", "Removed PERS", dumpPackage);
12873        }
12874
12875        if (mProcessesOnHold.size() > 0) {
12876            if (needSep) pw.println();
12877            needSep = true;
12878            printedAnything = true;
12879            pw.println("  Processes that are on old until the system is ready:");
12880            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12881                    "OnHold Norm", "OnHold PERS", dumpPackage);
12882        }
12883
12884        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12885
12886        if (mProcessCrashTimes.getMap().size() > 0) {
12887            boolean printed = false;
12888            long now = SystemClock.uptimeMillis();
12889            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12890            final int NP = pmap.size();
12891            for (int ip=0; ip<NP; ip++) {
12892                String pname = pmap.keyAt(ip);
12893                SparseArray<Long> uids = pmap.valueAt(ip);
12894                final int N = uids.size();
12895                for (int i=0; i<N; i++) {
12896                    int puid = uids.keyAt(i);
12897                    ProcessRecord r = mProcessNames.get(pname, puid);
12898                    if (dumpPackage != null && (r == null
12899                            || !r.pkgList.containsKey(dumpPackage))) {
12900                        continue;
12901                    }
12902                    if (!printed) {
12903                        if (needSep) pw.println();
12904                        needSep = true;
12905                        pw.println("  Time since processes crashed:");
12906                        printed = true;
12907                        printedAnything = true;
12908                    }
12909                    pw.print("    Process "); pw.print(pname);
12910                            pw.print(" uid "); pw.print(puid);
12911                            pw.print(": last crashed ");
12912                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12913                            pw.println(" ago");
12914                }
12915            }
12916        }
12917
12918        if (mBadProcesses.getMap().size() > 0) {
12919            boolean printed = false;
12920            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12921            final int NP = pmap.size();
12922            for (int ip=0; ip<NP; ip++) {
12923                String pname = pmap.keyAt(ip);
12924                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12925                final int N = uids.size();
12926                for (int i=0; i<N; i++) {
12927                    int puid = uids.keyAt(i);
12928                    ProcessRecord r = mProcessNames.get(pname, puid);
12929                    if (dumpPackage != null && (r == null
12930                            || !r.pkgList.containsKey(dumpPackage))) {
12931                        continue;
12932                    }
12933                    if (!printed) {
12934                        if (needSep) pw.println();
12935                        needSep = true;
12936                        pw.println("  Bad processes:");
12937                        printedAnything = true;
12938                    }
12939                    BadProcessInfo info = uids.valueAt(i);
12940                    pw.print("    Bad process "); pw.print(pname);
12941                            pw.print(" uid "); pw.print(puid);
12942                            pw.print(": crashed at time "); pw.println(info.time);
12943                    if (info.shortMsg != null) {
12944                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12945                    }
12946                    if (info.longMsg != null) {
12947                        pw.print("      Long msg: "); pw.println(info.longMsg);
12948                    }
12949                    if (info.stack != null) {
12950                        pw.println("      Stack:");
12951                        int lastPos = 0;
12952                        for (int pos=0; pos<info.stack.length(); pos++) {
12953                            if (info.stack.charAt(pos) == '\n') {
12954                                pw.print("        ");
12955                                pw.write(info.stack, lastPos, pos-lastPos);
12956                                pw.println();
12957                                lastPos = pos+1;
12958                            }
12959                        }
12960                        if (lastPos < info.stack.length()) {
12961                            pw.print("        ");
12962                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12963                            pw.println();
12964                        }
12965                    }
12966                }
12967            }
12968        }
12969
12970        if (dumpPackage == null) {
12971            pw.println();
12972            needSep = false;
12973            pw.println("  mStartedUsers:");
12974            for (int i=0; i<mStartedUsers.size(); i++) {
12975                UserStartedState uss = mStartedUsers.valueAt(i);
12976                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12977                        pw.print(": "); uss.dump("", pw);
12978            }
12979            pw.print("  mStartedUserArray: [");
12980            for (int i=0; i<mStartedUserArray.length; i++) {
12981                if (i > 0) pw.print(", ");
12982                pw.print(mStartedUserArray[i]);
12983            }
12984            pw.println("]");
12985            pw.print("  mUserLru: [");
12986            for (int i=0; i<mUserLru.size(); i++) {
12987                if (i > 0) pw.print(", ");
12988                pw.print(mUserLru.get(i));
12989            }
12990            pw.println("]");
12991            if (dumpAll) {
12992                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12993            }
12994            synchronized (mUserProfileGroupIdsSelfLocked) {
12995                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12996                    pw.println("  mUserProfileGroupIds:");
12997                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12998                        pw.print("    User #");
12999                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13000                        pw.print(" -> profile #");
13001                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13002                    }
13003                }
13004            }
13005        }
13006        if (mHomeProcess != null && (dumpPackage == null
13007                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13008            if (needSep) {
13009                pw.println();
13010                needSep = false;
13011            }
13012            pw.println("  mHomeProcess: " + mHomeProcess);
13013        }
13014        if (mPreviousProcess != null && (dumpPackage == null
13015                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13016            if (needSep) {
13017                pw.println();
13018                needSep = false;
13019            }
13020            pw.println("  mPreviousProcess: " + mPreviousProcess);
13021        }
13022        if (dumpAll) {
13023            StringBuilder sb = new StringBuilder(128);
13024            sb.append("  mPreviousProcessVisibleTime: ");
13025            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13026            pw.println(sb);
13027        }
13028        if (mHeavyWeightProcess != null && (dumpPackage == null
13029                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13030            if (needSep) {
13031                pw.println();
13032                needSep = false;
13033            }
13034            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13035        }
13036        if (dumpPackage == null) {
13037            pw.println("  mConfiguration: " + mConfiguration);
13038        }
13039        if (dumpAll) {
13040            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13041            if (mCompatModePackages.getPackages().size() > 0) {
13042                boolean printed = false;
13043                for (Map.Entry<String, Integer> entry
13044                        : mCompatModePackages.getPackages().entrySet()) {
13045                    String pkg = entry.getKey();
13046                    int mode = entry.getValue();
13047                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13048                        continue;
13049                    }
13050                    if (!printed) {
13051                        pw.println("  mScreenCompatPackages:");
13052                        printed = true;
13053                    }
13054                    pw.print("    "); pw.print(pkg); pw.print(": ");
13055                            pw.print(mode); pw.println();
13056                }
13057            }
13058        }
13059        if (dumpPackage == null) {
13060            pw.println("  mWakefulness="
13061                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13062            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13063                    + lockScreenShownToString());
13064            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13065                    + " mTestPssMode=" + mTestPssMode);
13066        }
13067        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13068                || mOrigWaitForDebugger) {
13069            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13070                    || dumpPackage.equals(mOrigDebugApp)) {
13071                if (needSep) {
13072                    pw.println();
13073                    needSep = false;
13074                }
13075                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13076                        + " mDebugTransient=" + mDebugTransient
13077                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13078            }
13079        }
13080        if (mOpenGlTraceApp != null) {
13081            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13082                if (needSep) {
13083                    pw.println();
13084                    needSep = false;
13085                }
13086                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13087            }
13088        }
13089        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13090                || mProfileFd != null) {
13091            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13092                if (needSep) {
13093                    pw.println();
13094                    needSep = false;
13095                }
13096                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13097                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13098                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13099                        + mAutoStopProfiler);
13100                pw.println("  mProfileType=" + mProfileType);
13101            }
13102        }
13103        if (dumpPackage == null) {
13104            if (mAlwaysFinishActivities || mController != null) {
13105                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13106                        + " mController=" + mController);
13107            }
13108            if (dumpAll) {
13109                pw.println("  Total persistent processes: " + numPers);
13110                pw.println("  mProcessesReady=" + mProcessesReady
13111                        + " mSystemReady=" + mSystemReady
13112                        + " mBooted=" + mBooted
13113                        + " mFactoryTest=" + mFactoryTest);
13114                pw.println("  mBooting=" + mBooting
13115                        + " mCallFinishBooting=" + mCallFinishBooting
13116                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13117                pw.print("  mLastPowerCheckRealtime=");
13118                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13119                        pw.println("");
13120                pw.print("  mLastPowerCheckUptime=");
13121                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13122                        pw.println("");
13123                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13124                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13125                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13126                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13127                        + " (" + mLruProcesses.size() + " total)"
13128                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13129                        + " mNumServiceProcs=" + mNumServiceProcs
13130                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13131                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13132                        + " mLastMemoryLevel" + mLastMemoryLevel
13133                        + " mLastNumProcesses" + mLastNumProcesses);
13134                long now = SystemClock.uptimeMillis();
13135                pw.print("  mLastIdleTime=");
13136                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13137                        pw.print(" mLowRamSinceLastIdle=");
13138                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13139                        pw.println();
13140            }
13141        }
13142
13143        if (!printedAnything) {
13144            pw.println("  (nothing)");
13145        }
13146    }
13147
13148    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13149            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13150        if (mProcessesToGc.size() > 0) {
13151            boolean printed = false;
13152            long now = SystemClock.uptimeMillis();
13153            for (int i=0; i<mProcessesToGc.size(); i++) {
13154                ProcessRecord proc = mProcessesToGc.get(i);
13155                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13156                    continue;
13157                }
13158                if (!printed) {
13159                    if (needSep) pw.println();
13160                    needSep = true;
13161                    pw.println("  Processes that are waiting to GC:");
13162                    printed = true;
13163                }
13164                pw.print("    Process "); pw.println(proc);
13165                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13166                        pw.print(", last gced=");
13167                        pw.print(now-proc.lastRequestedGc);
13168                        pw.print(" ms ago, last lowMem=");
13169                        pw.print(now-proc.lastLowMemory);
13170                        pw.println(" ms ago");
13171
13172            }
13173        }
13174        return needSep;
13175    }
13176
13177    void printOomLevel(PrintWriter pw, String name, int adj) {
13178        pw.print("    ");
13179        if (adj >= 0) {
13180            pw.print(' ');
13181            if (adj < 10) pw.print(' ');
13182        } else {
13183            if (adj > -10) pw.print(' ');
13184        }
13185        pw.print(adj);
13186        pw.print(": ");
13187        pw.print(name);
13188        pw.print(" (");
13189        pw.print(mProcessList.getMemLevel(adj)/1024);
13190        pw.println(" kB)");
13191    }
13192
13193    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13194            int opti, boolean dumpAll) {
13195        boolean needSep = false;
13196
13197        if (mLruProcesses.size() > 0) {
13198            if (needSep) pw.println();
13199            needSep = true;
13200            pw.println("  OOM levels:");
13201            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13202            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13203            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13204            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13205            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13206            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13207            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13208            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13209            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13210            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13211            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13212            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13213            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13214            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13215
13216            if (needSep) pw.println();
13217            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13218                    pw.print(" total, non-act at ");
13219                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13220                    pw.print(", non-svc at ");
13221                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13222                    pw.println("):");
13223            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13224            needSep = true;
13225        }
13226
13227        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13228
13229        pw.println();
13230        pw.println("  mHomeProcess: " + mHomeProcess);
13231        pw.println("  mPreviousProcess: " + mPreviousProcess);
13232        if (mHeavyWeightProcess != null) {
13233            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13234        }
13235
13236        return true;
13237    }
13238
13239    /**
13240     * There are three ways to call this:
13241     *  - no provider specified: dump all the providers
13242     *  - a flattened component name that matched an existing provider was specified as the
13243     *    first arg: dump that one provider
13244     *  - the first arg isn't the flattened component name of an existing provider:
13245     *    dump all providers whose component contains the first arg as a substring
13246     */
13247    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13248            int opti, boolean dumpAll) {
13249        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13250    }
13251
13252    static class ItemMatcher {
13253        ArrayList<ComponentName> components;
13254        ArrayList<String> strings;
13255        ArrayList<Integer> objects;
13256        boolean all;
13257
13258        ItemMatcher() {
13259            all = true;
13260        }
13261
13262        void build(String name) {
13263            ComponentName componentName = ComponentName.unflattenFromString(name);
13264            if (componentName != null) {
13265                if (components == null) {
13266                    components = new ArrayList<ComponentName>();
13267                }
13268                components.add(componentName);
13269                all = false;
13270            } else {
13271                int objectId = 0;
13272                // Not a '/' separated full component name; maybe an object ID?
13273                try {
13274                    objectId = Integer.parseInt(name, 16);
13275                    if (objects == null) {
13276                        objects = new ArrayList<Integer>();
13277                    }
13278                    objects.add(objectId);
13279                    all = false;
13280                } catch (RuntimeException e) {
13281                    // Not an integer; just do string match.
13282                    if (strings == null) {
13283                        strings = new ArrayList<String>();
13284                    }
13285                    strings.add(name);
13286                    all = false;
13287                }
13288            }
13289        }
13290
13291        int build(String[] args, int opti) {
13292            for (; opti<args.length; opti++) {
13293                String name = args[opti];
13294                if ("--".equals(name)) {
13295                    return opti+1;
13296                }
13297                build(name);
13298            }
13299            return opti;
13300        }
13301
13302        boolean match(Object object, ComponentName comp) {
13303            if (all) {
13304                return true;
13305            }
13306            if (components != null) {
13307                for (int i=0; i<components.size(); i++) {
13308                    if (components.get(i).equals(comp)) {
13309                        return true;
13310                    }
13311                }
13312            }
13313            if (objects != null) {
13314                for (int i=0; i<objects.size(); i++) {
13315                    if (System.identityHashCode(object) == objects.get(i)) {
13316                        return true;
13317                    }
13318                }
13319            }
13320            if (strings != null) {
13321                String flat = comp.flattenToString();
13322                for (int i=0; i<strings.size(); i++) {
13323                    if (flat.contains(strings.get(i))) {
13324                        return true;
13325                    }
13326                }
13327            }
13328            return false;
13329        }
13330    }
13331
13332    /**
13333     * There are three things that cmd can be:
13334     *  - a flattened component name that matches an existing activity
13335     *  - the cmd arg isn't the flattened component name of an existing activity:
13336     *    dump all activity whose component contains the cmd as a substring
13337     *  - A hex number of the ActivityRecord object instance.
13338     */
13339    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13340            int opti, boolean dumpAll) {
13341        ArrayList<ActivityRecord> activities;
13342
13343        synchronized (this) {
13344            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13345        }
13346
13347        if (activities.size() <= 0) {
13348            return false;
13349        }
13350
13351        String[] newArgs = new String[args.length - opti];
13352        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13353
13354        TaskRecord lastTask = null;
13355        boolean needSep = false;
13356        for (int i=activities.size()-1; i>=0; i--) {
13357            ActivityRecord r = activities.get(i);
13358            if (needSep) {
13359                pw.println();
13360            }
13361            needSep = true;
13362            synchronized (this) {
13363                if (lastTask != r.task) {
13364                    lastTask = r.task;
13365                    pw.print("TASK "); pw.print(lastTask.affinity);
13366                            pw.print(" id="); pw.println(lastTask.taskId);
13367                    if (dumpAll) {
13368                        lastTask.dump(pw, "  ");
13369                    }
13370                }
13371            }
13372            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13373        }
13374        return true;
13375    }
13376
13377    /**
13378     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13379     * there is a thread associated with the activity.
13380     */
13381    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13382            final ActivityRecord r, String[] args, boolean dumpAll) {
13383        String innerPrefix = prefix + "  ";
13384        synchronized (this) {
13385            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13386                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13387                    pw.print(" pid=");
13388                    if (r.app != null) pw.println(r.app.pid);
13389                    else pw.println("(not running)");
13390            if (dumpAll) {
13391                r.dump(pw, innerPrefix);
13392            }
13393        }
13394        if (r.app != null && r.app.thread != null) {
13395            // flush anything that is already in the PrintWriter since the thread is going
13396            // to write to the file descriptor directly
13397            pw.flush();
13398            try {
13399                TransferPipe tp = new TransferPipe();
13400                try {
13401                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13402                            r.appToken, innerPrefix, args);
13403                    tp.go(fd);
13404                } finally {
13405                    tp.kill();
13406                }
13407            } catch (IOException e) {
13408                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13409            } catch (RemoteException e) {
13410                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13411            }
13412        }
13413    }
13414
13415    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13416            int opti, boolean dumpAll, String dumpPackage) {
13417        boolean needSep = false;
13418        boolean onlyHistory = false;
13419        boolean printedAnything = false;
13420
13421        if ("history".equals(dumpPackage)) {
13422            if (opti < args.length && "-s".equals(args[opti])) {
13423                dumpAll = false;
13424            }
13425            onlyHistory = true;
13426            dumpPackage = null;
13427        }
13428
13429        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13430        if (!onlyHistory && dumpAll) {
13431            if (mRegisteredReceivers.size() > 0) {
13432                boolean printed = false;
13433                Iterator it = mRegisteredReceivers.values().iterator();
13434                while (it.hasNext()) {
13435                    ReceiverList r = (ReceiverList)it.next();
13436                    if (dumpPackage != null && (r.app == null ||
13437                            !dumpPackage.equals(r.app.info.packageName))) {
13438                        continue;
13439                    }
13440                    if (!printed) {
13441                        pw.println("  Registered Receivers:");
13442                        needSep = true;
13443                        printed = true;
13444                        printedAnything = true;
13445                    }
13446                    pw.print("  * "); pw.println(r);
13447                    r.dump(pw, "    ");
13448                }
13449            }
13450
13451            if (mReceiverResolver.dump(pw, needSep ?
13452                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13453                    "    ", dumpPackage, false, false)) {
13454                needSep = true;
13455                printedAnything = true;
13456            }
13457        }
13458
13459        for (BroadcastQueue q : mBroadcastQueues) {
13460            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13461            printedAnything |= needSep;
13462        }
13463
13464        needSep = true;
13465
13466        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13467            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13468                if (needSep) {
13469                    pw.println();
13470                }
13471                needSep = true;
13472                printedAnything = true;
13473                pw.print("  Sticky broadcasts for user ");
13474                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13475                StringBuilder sb = new StringBuilder(128);
13476                for (Map.Entry<String, ArrayList<Intent>> ent
13477                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13478                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13479                    if (dumpAll) {
13480                        pw.println(":");
13481                        ArrayList<Intent> intents = ent.getValue();
13482                        final int N = intents.size();
13483                        for (int i=0; i<N; i++) {
13484                            sb.setLength(0);
13485                            sb.append("    Intent: ");
13486                            intents.get(i).toShortString(sb, false, true, false, false);
13487                            pw.println(sb.toString());
13488                            Bundle bundle = intents.get(i).getExtras();
13489                            if (bundle != null) {
13490                                pw.print("      ");
13491                                pw.println(bundle.toString());
13492                            }
13493                        }
13494                    } else {
13495                        pw.println("");
13496                    }
13497                }
13498            }
13499        }
13500
13501        if (!onlyHistory && dumpAll) {
13502            pw.println();
13503            for (BroadcastQueue queue : mBroadcastQueues) {
13504                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13505                        + queue.mBroadcastsScheduled);
13506            }
13507            pw.println("  mHandler:");
13508            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13509            needSep = true;
13510            printedAnything = true;
13511        }
13512
13513        if (!printedAnything) {
13514            pw.println("  (nothing)");
13515        }
13516    }
13517
13518    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13519            int opti, boolean dumpAll, String dumpPackage) {
13520        boolean needSep;
13521        boolean printedAnything = false;
13522
13523        ItemMatcher matcher = new ItemMatcher();
13524        matcher.build(args, opti);
13525
13526        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13527
13528        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13529        printedAnything |= needSep;
13530
13531        if (mLaunchingProviders.size() > 0) {
13532            boolean printed = false;
13533            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13534                ContentProviderRecord r = mLaunchingProviders.get(i);
13535                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13536                    continue;
13537                }
13538                if (!printed) {
13539                    if (needSep) pw.println();
13540                    needSep = true;
13541                    pw.println("  Launching content providers:");
13542                    printed = true;
13543                    printedAnything = true;
13544                }
13545                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13546                        pw.println(r);
13547            }
13548        }
13549
13550        if (mGrantedUriPermissions.size() > 0) {
13551            boolean printed = false;
13552            int dumpUid = -2;
13553            if (dumpPackage != null) {
13554                try {
13555                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13556                } catch (NameNotFoundException e) {
13557                    dumpUid = -1;
13558                }
13559            }
13560            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13561                int uid = mGrantedUriPermissions.keyAt(i);
13562                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13563                    continue;
13564                }
13565                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13566                if (!printed) {
13567                    if (needSep) pw.println();
13568                    needSep = true;
13569                    pw.println("  Granted Uri Permissions:");
13570                    printed = true;
13571                    printedAnything = true;
13572                }
13573                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13574                for (UriPermission perm : perms.values()) {
13575                    pw.print("    "); pw.println(perm);
13576                    if (dumpAll) {
13577                        perm.dump(pw, "      ");
13578                    }
13579                }
13580            }
13581        }
13582
13583        if (!printedAnything) {
13584            pw.println("  (nothing)");
13585        }
13586    }
13587
13588    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13589            int opti, boolean dumpAll, String dumpPackage) {
13590        boolean printed = false;
13591
13592        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13593
13594        if (mIntentSenderRecords.size() > 0) {
13595            Iterator<WeakReference<PendingIntentRecord>> it
13596                    = mIntentSenderRecords.values().iterator();
13597            while (it.hasNext()) {
13598                WeakReference<PendingIntentRecord> ref = it.next();
13599                PendingIntentRecord rec = ref != null ? ref.get(): null;
13600                if (dumpPackage != null && (rec == null
13601                        || !dumpPackage.equals(rec.key.packageName))) {
13602                    continue;
13603                }
13604                printed = true;
13605                if (rec != null) {
13606                    pw.print("  * "); pw.println(rec);
13607                    if (dumpAll) {
13608                        rec.dump(pw, "    ");
13609                    }
13610                } else {
13611                    pw.print("  * "); pw.println(ref);
13612                }
13613            }
13614        }
13615
13616        if (!printed) {
13617            pw.println("  (nothing)");
13618        }
13619    }
13620
13621    private static final int dumpProcessList(PrintWriter pw,
13622            ActivityManagerService service, List list,
13623            String prefix, String normalLabel, String persistentLabel,
13624            String dumpPackage) {
13625        int numPers = 0;
13626        final int N = list.size()-1;
13627        for (int i=N; i>=0; i--) {
13628            ProcessRecord r = (ProcessRecord)list.get(i);
13629            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13630                continue;
13631            }
13632            pw.println(String.format("%s%s #%2d: %s",
13633                    prefix, (r.persistent ? persistentLabel : normalLabel),
13634                    i, r.toString()));
13635            if (r.persistent) {
13636                numPers++;
13637            }
13638        }
13639        return numPers;
13640    }
13641
13642    private static final boolean dumpProcessOomList(PrintWriter pw,
13643            ActivityManagerService service, List<ProcessRecord> origList,
13644            String prefix, String normalLabel, String persistentLabel,
13645            boolean inclDetails, String dumpPackage) {
13646
13647        ArrayList<Pair<ProcessRecord, Integer>> list
13648                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13649        for (int i=0; i<origList.size(); i++) {
13650            ProcessRecord r = origList.get(i);
13651            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13652                continue;
13653            }
13654            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13655        }
13656
13657        if (list.size() <= 0) {
13658            return false;
13659        }
13660
13661        Comparator<Pair<ProcessRecord, Integer>> comparator
13662                = new Comparator<Pair<ProcessRecord, Integer>>() {
13663            @Override
13664            public int compare(Pair<ProcessRecord, Integer> object1,
13665                    Pair<ProcessRecord, Integer> object2) {
13666                if (object1.first.setAdj != object2.first.setAdj) {
13667                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13668                }
13669                if (object1.second.intValue() != object2.second.intValue()) {
13670                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13671                }
13672                return 0;
13673            }
13674        };
13675
13676        Collections.sort(list, comparator);
13677
13678        final long curRealtime = SystemClock.elapsedRealtime();
13679        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13680        final long curUptime = SystemClock.uptimeMillis();
13681        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13682
13683        for (int i=list.size()-1; i>=0; i--) {
13684            ProcessRecord r = list.get(i).first;
13685            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13686            char schedGroup;
13687            switch (r.setSchedGroup) {
13688                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13689                    schedGroup = 'B';
13690                    break;
13691                case Process.THREAD_GROUP_DEFAULT:
13692                    schedGroup = 'F';
13693                    break;
13694                default:
13695                    schedGroup = '?';
13696                    break;
13697            }
13698            char foreground;
13699            if (r.foregroundActivities) {
13700                foreground = 'A';
13701            } else if (r.foregroundServices) {
13702                foreground = 'S';
13703            } else {
13704                foreground = ' ';
13705            }
13706            String procState = ProcessList.makeProcStateString(r.curProcState);
13707            pw.print(prefix);
13708            pw.print(r.persistent ? persistentLabel : normalLabel);
13709            pw.print(" #");
13710            int num = (origList.size()-1)-list.get(i).second;
13711            if (num < 10) pw.print(' ');
13712            pw.print(num);
13713            pw.print(": ");
13714            pw.print(oomAdj);
13715            pw.print(' ');
13716            pw.print(schedGroup);
13717            pw.print('/');
13718            pw.print(foreground);
13719            pw.print('/');
13720            pw.print(procState);
13721            pw.print(" trm:");
13722            if (r.trimMemoryLevel < 10) pw.print(' ');
13723            pw.print(r.trimMemoryLevel);
13724            pw.print(' ');
13725            pw.print(r.toShortString());
13726            pw.print(" (");
13727            pw.print(r.adjType);
13728            pw.println(')');
13729            if (r.adjSource != null || r.adjTarget != null) {
13730                pw.print(prefix);
13731                pw.print("    ");
13732                if (r.adjTarget instanceof ComponentName) {
13733                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13734                } else if (r.adjTarget != null) {
13735                    pw.print(r.adjTarget.toString());
13736                } else {
13737                    pw.print("{null}");
13738                }
13739                pw.print("<=");
13740                if (r.adjSource instanceof ProcessRecord) {
13741                    pw.print("Proc{");
13742                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13743                    pw.println("}");
13744                } else if (r.adjSource != null) {
13745                    pw.println(r.adjSource.toString());
13746                } else {
13747                    pw.println("{null}");
13748                }
13749            }
13750            if (inclDetails) {
13751                pw.print(prefix);
13752                pw.print("    ");
13753                pw.print("oom: max="); pw.print(r.maxAdj);
13754                pw.print(" curRaw="); pw.print(r.curRawAdj);
13755                pw.print(" setRaw="); pw.print(r.setRawAdj);
13756                pw.print(" cur="); pw.print(r.curAdj);
13757                pw.print(" set="); pw.println(r.setAdj);
13758                pw.print(prefix);
13759                pw.print("    ");
13760                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13761                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13762                pw.print(" lastPss="); pw.print(r.lastPss);
13763                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13764                pw.print(prefix);
13765                pw.print("    ");
13766                pw.print("cached="); pw.print(r.cached);
13767                pw.print(" empty="); pw.print(r.empty);
13768                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13769
13770                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13771                    if (r.lastWakeTime != 0) {
13772                        long wtime;
13773                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13774                        synchronized (stats) {
13775                            wtime = stats.getProcessWakeTime(r.info.uid,
13776                                    r.pid, curRealtime);
13777                        }
13778                        long timeUsed = wtime - r.lastWakeTime;
13779                        pw.print(prefix);
13780                        pw.print("    ");
13781                        pw.print("keep awake over ");
13782                        TimeUtils.formatDuration(realtimeSince, pw);
13783                        pw.print(" used ");
13784                        TimeUtils.formatDuration(timeUsed, pw);
13785                        pw.print(" (");
13786                        pw.print((timeUsed*100)/realtimeSince);
13787                        pw.println("%)");
13788                    }
13789                    if (r.lastCpuTime != 0) {
13790                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13791                        pw.print(prefix);
13792                        pw.print("    ");
13793                        pw.print("run cpu over ");
13794                        TimeUtils.formatDuration(uptimeSince, pw);
13795                        pw.print(" used ");
13796                        TimeUtils.formatDuration(timeUsed, pw);
13797                        pw.print(" (");
13798                        pw.print((timeUsed*100)/uptimeSince);
13799                        pw.println("%)");
13800                    }
13801                }
13802            }
13803        }
13804        return true;
13805    }
13806
13807    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13808            String[] args) {
13809        ArrayList<ProcessRecord> procs;
13810        synchronized (this) {
13811            if (args != null && args.length > start
13812                    && args[start].charAt(0) != '-') {
13813                procs = new ArrayList<ProcessRecord>();
13814                int pid = -1;
13815                try {
13816                    pid = Integer.parseInt(args[start]);
13817                } catch (NumberFormatException e) {
13818                }
13819                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13820                    ProcessRecord proc = mLruProcesses.get(i);
13821                    if (proc.pid == pid) {
13822                        procs.add(proc);
13823                    } else if (allPkgs && proc.pkgList != null
13824                            && proc.pkgList.containsKey(args[start])) {
13825                        procs.add(proc);
13826                    } else if (proc.processName.equals(args[start])) {
13827                        procs.add(proc);
13828                    }
13829                }
13830                if (procs.size() <= 0) {
13831                    return null;
13832                }
13833            } else {
13834                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13835            }
13836        }
13837        return procs;
13838    }
13839
13840    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13841            PrintWriter pw, String[] args) {
13842        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13843        if (procs == null) {
13844            pw.println("No process found for: " + args[0]);
13845            return;
13846        }
13847
13848        long uptime = SystemClock.uptimeMillis();
13849        long realtime = SystemClock.elapsedRealtime();
13850        pw.println("Applications Graphics Acceleration Info:");
13851        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13852
13853        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13854            ProcessRecord r = procs.get(i);
13855            if (r.thread != null) {
13856                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13857                pw.flush();
13858                try {
13859                    TransferPipe tp = new TransferPipe();
13860                    try {
13861                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13862                        tp.go(fd);
13863                    } finally {
13864                        tp.kill();
13865                    }
13866                } catch (IOException e) {
13867                    pw.println("Failure while dumping the app: " + r);
13868                    pw.flush();
13869                } catch (RemoteException e) {
13870                    pw.println("Got a RemoteException while dumping the app " + r);
13871                    pw.flush();
13872                }
13873            }
13874        }
13875    }
13876
13877    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13878        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13879        if (procs == null) {
13880            pw.println("No process found for: " + args[0]);
13881            return;
13882        }
13883
13884        pw.println("Applications Database Info:");
13885
13886        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13887            ProcessRecord r = procs.get(i);
13888            if (r.thread != null) {
13889                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13890                pw.flush();
13891                try {
13892                    TransferPipe tp = new TransferPipe();
13893                    try {
13894                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13895                        tp.go(fd);
13896                    } finally {
13897                        tp.kill();
13898                    }
13899                } catch (IOException e) {
13900                    pw.println("Failure while dumping the app: " + r);
13901                    pw.flush();
13902                } catch (RemoteException e) {
13903                    pw.println("Got a RemoteException while dumping the app " + r);
13904                    pw.flush();
13905                }
13906            }
13907        }
13908    }
13909
13910    final static class MemItem {
13911        final boolean isProc;
13912        final String label;
13913        final String shortLabel;
13914        final long pss;
13915        final int id;
13916        final boolean hasActivities;
13917        ArrayList<MemItem> subitems;
13918
13919        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13920                boolean _hasActivities) {
13921            isProc = true;
13922            label = _label;
13923            shortLabel = _shortLabel;
13924            pss = _pss;
13925            id = _id;
13926            hasActivities = _hasActivities;
13927        }
13928
13929        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13930            isProc = false;
13931            label = _label;
13932            shortLabel = _shortLabel;
13933            pss = _pss;
13934            id = _id;
13935            hasActivities = false;
13936        }
13937    }
13938
13939    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13940            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13941        if (sort && !isCompact) {
13942            Collections.sort(items, new Comparator<MemItem>() {
13943                @Override
13944                public int compare(MemItem lhs, MemItem rhs) {
13945                    if (lhs.pss < rhs.pss) {
13946                        return 1;
13947                    } else if (lhs.pss > rhs.pss) {
13948                        return -1;
13949                    }
13950                    return 0;
13951                }
13952            });
13953        }
13954
13955        for (int i=0; i<items.size(); i++) {
13956            MemItem mi = items.get(i);
13957            if (!isCompact) {
13958                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13959            } else if (mi.isProc) {
13960                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13961                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13962                pw.println(mi.hasActivities ? ",a" : ",e");
13963            } else {
13964                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13965                pw.println(mi.pss);
13966            }
13967            if (mi.subitems != null) {
13968                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13969                        true, isCompact);
13970            }
13971        }
13972    }
13973
13974    // These are in KB.
13975    static final long[] DUMP_MEM_BUCKETS = new long[] {
13976        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13977        120*1024, 160*1024, 200*1024,
13978        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13979        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13980    };
13981
13982    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13983            boolean stackLike) {
13984        int start = label.lastIndexOf('.');
13985        if (start >= 0) start++;
13986        else start = 0;
13987        int end = label.length();
13988        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13989            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13990                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13991                out.append(bucket);
13992                out.append(stackLike ? "MB." : "MB ");
13993                out.append(label, start, end);
13994                return;
13995            }
13996        }
13997        out.append(memKB/1024);
13998        out.append(stackLike ? "MB." : "MB ");
13999        out.append(label, start, end);
14000    }
14001
14002    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14003            ProcessList.NATIVE_ADJ,
14004            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14005            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14006            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14007            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14008            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14009            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14010    };
14011    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14012            "Native",
14013            "System", "Persistent", "Persistent Service", "Foreground",
14014            "Visible", "Perceptible",
14015            "Heavy Weight", "Backup",
14016            "A Services", "Home",
14017            "Previous", "B Services", "Cached"
14018    };
14019    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14020            "native",
14021            "sys", "pers", "persvc", "fore",
14022            "vis", "percept",
14023            "heavy", "backup",
14024            "servicea", "home",
14025            "prev", "serviceb", "cached"
14026    };
14027
14028    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14029            long realtime, boolean isCheckinRequest, boolean isCompact) {
14030        if (isCheckinRequest || isCompact) {
14031            // short checkin version
14032            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14033        } else {
14034            pw.println("Applications Memory Usage (kB):");
14035            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14036        }
14037    }
14038
14039    private static final int KSM_SHARED = 0;
14040    private static final int KSM_SHARING = 1;
14041    private static final int KSM_UNSHARED = 2;
14042    private static final int KSM_VOLATILE = 3;
14043
14044    private final long[] getKsmInfo() {
14045        long[] longOut = new long[4];
14046        final int[] SINGLE_LONG_FORMAT = new int[] {
14047            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14048        };
14049        long[] longTmp = new long[1];
14050        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14051                SINGLE_LONG_FORMAT, null, longTmp, null);
14052        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14053        longTmp[0] = 0;
14054        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14055                SINGLE_LONG_FORMAT, null, longTmp, null);
14056        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14057        longTmp[0] = 0;
14058        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14059                SINGLE_LONG_FORMAT, null, longTmp, null);
14060        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14061        longTmp[0] = 0;
14062        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14063                SINGLE_LONG_FORMAT, null, longTmp, null);
14064        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14065        return longOut;
14066    }
14067
14068    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14069            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14070        boolean dumpDetails = false;
14071        boolean dumpFullDetails = false;
14072        boolean dumpDalvik = false;
14073        boolean oomOnly = false;
14074        boolean isCompact = false;
14075        boolean localOnly = false;
14076        boolean packages = false;
14077
14078        int opti = 0;
14079        while (opti < args.length) {
14080            String opt = args[opti];
14081            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14082                break;
14083            }
14084            opti++;
14085            if ("-a".equals(opt)) {
14086                dumpDetails = true;
14087                dumpFullDetails = true;
14088                dumpDalvik = true;
14089            } else if ("-d".equals(opt)) {
14090                dumpDalvik = true;
14091            } else if ("-c".equals(opt)) {
14092                isCompact = true;
14093            } else if ("--oom".equals(opt)) {
14094                oomOnly = true;
14095            } else if ("--local".equals(opt)) {
14096                localOnly = true;
14097            } else if ("--package".equals(opt)) {
14098                packages = true;
14099            } else if ("-h".equals(opt)) {
14100                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14101                pw.println("  -a: include all available information for each process.");
14102                pw.println("  -d: include dalvik details when dumping process details.");
14103                pw.println("  -c: dump in a compact machine-parseable representation.");
14104                pw.println("  --oom: only show processes organized by oom adj.");
14105                pw.println("  --local: only collect details locally, don't call process.");
14106                pw.println("  --package: interpret process arg as package, dumping all");
14107                pw.println("             processes that have loaded that package.");
14108                pw.println("If [process] is specified it can be the name or ");
14109                pw.println("pid of a specific process to dump.");
14110                return;
14111            } else {
14112                pw.println("Unknown argument: " + opt + "; use -h for help");
14113            }
14114        }
14115
14116        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14117        long uptime = SystemClock.uptimeMillis();
14118        long realtime = SystemClock.elapsedRealtime();
14119        final long[] tmpLong = new long[1];
14120
14121        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14122        if (procs == null) {
14123            // No Java processes.  Maybe they want to print a native process.
14124            if (args != null && args.length > opti
14125                    && args[opti].charAt(0) != '-') {
14126                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14127                        = new ArrayList<ProcessCpuTracker.Stats>();
14128                updateCpuStatsNow();
14129                int findPid = -1;
14130                try {
14131                    findPid = Integer.parseInt(args[opti]);
14132                } catch (NumberFormatException e) {
14133                }
14134                synchronized (mProcessCpuTracker) {
14135                    final int N = mProcessCpuTracker.countStats();
14136                    for (int i=0; i<N; i++) {
14137                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14138                        if (st.pid == findPid || (st.baseName != null
14139                                && st.baseName.equals(args[opti]))) {
14140                            nativeProcs.add(st);
14141                        }
14142                    }
14143                }
14144                if (nativeProcs.size() > 0) {
14145                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14146                            isCompact);
14147                    Debug.MemoryInfo mi = null;
14148                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14149                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14150                        final int pid = r.pid;
14151                        if (!isCheckinRequest && dumpDetails) {
14152                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14153                        }
14154                        if (mi == null) {
14155                            mi = new Debug.MemoryInfo();
14156                        }
14157                        if (dumpDetails || (!brief && !oomOnly)) {
14158                            Debug.getMemoryInfo(pid, mi);
14159                        } else {
14160                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14161                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14162                        }
14163                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14164                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14165                        if (isCheckinRequest) {
14166                            pw.println();
14167                        }
14168                    }
14169                    return;
14170                }
14171            }
14172            pw.println("No process found for: " + args[opti]);
14173            return;
14174        }
14175
14176        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14177            dumpDetails = true;
14178        }
14179
14180        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14181
14182        String[] innerArgs = new String[args.length-opti];
14183        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14184
14185        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14186        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14187        long nativePss = 0;
14188        long dalvikPss = 0;
14189        long otherPss = 0;
14190        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14191
14192        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14193        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14194                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14195
14196        long totalPss = 0;
14197        long cachedPss = 0;
14198
14199        Debug.MemoryInfo mi = null;
14200        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14201            final ProcessRecord r = procs.get(i);
14202            final IApplicationThread thread;
14203            final int pid;
14204            final int oomAdj;
14205            final boolean hasActivities;
14206            synchronized (this) {
14207                thread = r.thread;
14208                pid = r.pid;
14209                oomAdj = r.getSetAdjWithServices();
14210                hasActivities = r.activities.size() > 0;
14211            }
14212            if (thread != null) {
14213                if (!isCheckinRequest && dumpDetails) {
14214                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14215                }
14216                if (mi == null) {
14217                    mi = new Debug.MemoryInfo();
14218                }
14219                if (dumpDetails || (!brief && !oomOnly)) {
14220                    Debug.getMemoryInfo(pid, mi);
14221                } else {
14222                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14223                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14224                }
14225                if (dumpDetails) {
14226                    if (localOnly) {
14227                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14228                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14229                        if (isCheckinRequest) {
14230                            pw.println();
14231                        }
14232                    } else {
14233                        try {
14234                            pw.flush();
14235                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14236                                    dumpDalvik, innerArgs);
14237                        } catch (RemoteException e) {
14238                            if (!isCheckinRequest) {
14239                                pw.println("Got RemoteException!");
14240                                pw.flush();
14241                            }
14242                        }
14243                    }
14244                }
14245
14246                final long myTotalPss = mi.getTotalPss();
14247                final long myTotalUss = mi.getTotalUss();
14248
14249                synchronized (this) {
14250                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14251                        // Record this for posterity if the process has been stable.
14252                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14253                    }
14254                }
14255
14256                if (!isCheckinRequest && mi != null) {
14257                    totalPss += myTotalPss;
14258                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14259                            (hasActivities ? " / activities)" : ")"),
14260                            r.processName, myTotalPss, pid, hasActivities);
14261                    procMems.add(pssItem);
14262                    procMemsMap.put(pid, pssItem);
14263
14264                    nativePss += mi.nativePss;
14265                    dalvikPss += mi.dalvikPss;
14266                    otherPss += mi.otherPss;
14267                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14268                        long mem = mi.getOtherPss(j);
14269                        miscPss[j] += mem;
14270                        otherPss -= mem;
14271                    }
14272
14273                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14274                        cachedPss += myTotalPss;
14275                    }
14276
14277                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14278                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14279                                || oomIndex == (oomPss.length-1)) {
14280                            oomPss[oomIndex] += myTotalPss;
14281                            if (oomProcs[oomIndex] == null) {
14282                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14283                            }
14284                            oomProcs[oomIndex].add(pssItem);
14285                            break;
14286                        }
14287                    }
14288                }
14289            }
14290        }
14291
14292        long nativeProcTotalPss = 0;
14293
14294        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14295            // If we are showing aggregations, also look for native processes to
14296            // include so that our aggregations are more accurate.
14297            updateCpuStatsNow();
14298            mi = null;
14299            synchronized (mProcessCpuTracker) {
14300                final int N = mProcessCpuTracker.countStats();
14301                for (int i=0; i<N; i++) {
14302                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14303                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14304                        if (mi == null) {
14305                            mi = new Debug.MemoryInfo();
14306                        }
14307                        if (!brief && !oomOnly) {
14308                            Debug.getMemoryInfo(st.pid, mi);
14309                        } else {
14310                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14311                            mi.nativePrivateDirty = (int)tmpLong[0];
14312                        }
14313
14314                        final long myTotalPss = mi.getTotalPss();
14315                        totalPss += myTotalPss;
14316                        nativeProcTotalPss += myTotalPss;
14317
14318                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14319                                st.name, myTotalPss, st.pid, false);
14320                        procMems.add(pssItem);
14321
14322                        nativePss += mi.nativePss;
14323                        dalvikPss += mi.dalvikPss;
14324                        otherPss += mi.otherPss;
14325                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14326                            long mem = mi.getOtherPss(j);
14327                            miscPss[j] += mem;
14328                            otherPss -= mem;
14329                        }
14330                        oomPss[0] += myTotalPss;
14331                        if (oomProcs[0] == null) {
14332                            oomProcs[0] = new ArrayList<MemItem>();
14333                        }
14334                        oomProcs[0].add(pssItem);
14335                    }
14336                }
14337            }
14338
14339            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14340
14341            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14342            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14343            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14344            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14345                String label = Debug.MemoryInfo.getOtherLabel(j);
14346                catMems.add(new MemItem(label, label, miscPss[j], j));
14347            }
14348
14349            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14350            for (int j=0; j<oomPss.length; j++) {
14351                if (oomPss[j] != 0) {
14352                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14353                            : DUMP_MEM_OOM_LABEL[j];
14354                    MemItem item = new MemItem(label, label, oomPss[j],
14355                            DUMP_MEM_OOM_ADJ[j]);
14356                    item.subitems = oomProcs[j];
14357                    oomMems.add(item);
14358                }
14359            }
14360
14361            if (!brief && !oomOnly && !isCompact) {
14362                pw.println();
14363                pw.println("Total PSS by process:");
14364                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14365                pw.println();
14366            }
14367            if (!isCompact) {
14368                pw.println("Total PSS by OOM adjustment:");
14369            }
14370            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14371            if (!brief && !oomOnly) {
14372                PrintWriter out = categoryPw != null ? categoryPw : pw;
14373                if (!isCompact) {
14374                    out.println();
14375                    out.println("Total PSS by category:");
14376                }
14377                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14378            }
14379            if (!isCompact) {
14380                pw.println();
14381            }
14382            MemInfoReader memInfo = new MemInfoReader();
14383            memInfo.readMemInfo();
14384            if (nativeProcTotalPss > 0) {
14385                synchronized (this) {
14386                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14387                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14388                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14389                }
14390            }
14391            if (!brief) {
14392                if (!isCompact) {
14393                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14394                    pw.print(" kB (status ");
14395                    switch (mLastMemoryLevel) {
14396                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14397                            pw.println("normal)");
14398                            break;
14399                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14400                            pw.println("moderate)");
14401                            break;
14402                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14403                            pw.println("low)");
14404                            break;
14405                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14406                            pw.println("critical)");
14407                            break;
14408                        default:
14409                            pw.print(mLastMemoryLevel);
14410                            pw.println(")");
14411                            break;
14412                    }
14413                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14414                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14415                            pw.print(cachedPss); pw.print(" cached pss + ");
14416                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14417                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14418                } else {
14419                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14420                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14421                            + memInfo.getFreeSizeKb()); pw.print(",");
14422                    pw.println(totalPss - cachedPss);
14423                }
14424            }
14425            if (!isCompact) {
14426                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14427                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14428                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14429                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14430                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14431                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14432                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14433            }
14434            if (!brief) {
14435                if (memInfo.getZramTotalSizeKb() != 0) {
14436                    if (!isCompact) {
14437                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14438                                pw.print(" kB physical used for ");
14439                                pw.print(memInfo.getSwapTotalSizeKb()
14440                                        - memInfo.getSwapFreeSizeKb());
14441                                pw.print(" kB in swap (");
14442                                pw.print(memInfo.getSwapTotalSizeKb());
14443                                pw.println(" kB total swap)");
14444                    } else {
14445                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14446                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14447                                pw.println(memInfo.getSwapFreeSizeKb());
14448                    }
14449                }
14450                final long[] ksm = getKsmInfo();
14451                if (!isCompact) {
14452                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14453                            || ksm[KSM_VOLATILE] != 0) {
14454                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14455                                pw.print(" kB saved from shared ");
14456                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14457                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14458                                pw.print(" kB unshared; ");
14459                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14460                    }
14461                    pw.print("   Tuning: ");
14462                    pw.print(ActivityManager.staticGetMemoryClass());
14463                    pw.print(" (large ");
14464                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14465                    pw.print("), oom ");
14466                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14467                    pw.print(" kB");
14468                    pw.print(", restore limit ");
14469                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14470                    pw.print(" kB");
14471                    if (ActivityManager.isLowRamDeviceStatic()) {
14472                        pw.print(" (low-ram)");
14473                    }
14474                    if (ActivityManager.isHighEndGfx()) {
14475                        pw.print(" (high-end-gfx)");
14476                    }
14477                    pw.println();
14478                } else {
14479                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14480                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14481                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14482                    pw.print("tuning,");
14483                    pw.print(ActivityManager.staticGetMemoryClass());
14484                    pw.print(',');
14485                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14486                    pw.print(',');
14487                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14488                    if (ActivityManager.isLowRamDeviceStatic()) {
14489                        pw.print(",low-ram");
14490                    }
14491                    if (ActivityManager.isHighEndGfx()) {
14492                        pw.print(",high-end-gfx");
14493                    }
14494                    pw.println();
14495                }
14496            }
14497        }
14498    }
14499
14500    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14501            long memtrack, String name) {
14502        sb.append("  ");
14503        sb.append(ProcessList.makeOomAdjString(oomAdj));
14504        sb.append(' ');
14505        sb.append(ProcessList.makeProcStateString(procState));
14506        sb.append(' ');
14507        ProcessList.appendRamKb(sb, pss);
14508        sb.append(" kB: ");
14509        sb.append(name);
14510        if (memtrack > 0) {
14511            sb.append(" (");
14512            sb.append(memtrack);
14513            sb.append(" kB memtrack)");
14514        }
14515    }
14516
14517    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14518        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14519        sb.append(" (pid ");
14520        sb.append(mi.pid);
14521        sb.append(") ");
14522        sb.append(mi.adjType);
14523        sb.append('\n');
14524        if (mi.adjReason != null) {
14525            sb.append("                      ");
14526            sb.append(mi.adjReason);
14527            sb.append('\n');
14528        }
14529    }
14530
14531    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14532        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14533        for (int i=0, N=memInfos.size(); i<N; i++) {
14534            ProcessMemInfo mi = memInfos.get(i);
14535            infoMap.put(mi.pid, mi);
14536        }
14537        updateCpuStatsNow();
14538        long[] memtrackTmp = new long[1];
14539        synchronized (mProcessCpuTracker) {
14540            final int N = mProcessCpuTracker.countStats();
14541            for (int i=0; i<N; i++) {
14542                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14543                if (st.vsize > 0) {
14544                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14545                    if (pss > 0) {
14546                        if (infoMap.indexOfKey(st.pid) < 0) {
14547                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14548                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14549                            mi.pss = pss;
14550                            mi.memtrack = memtrackTmp[0];
14551                            memInfos.add(mi);
14552                        }
14553                    }
14554                }
14555            }
14556        }
14557
14558        long totalPss = 0;
14559        long totalMemtrack = 0;
14560        for (int i=0, N=memInfos.size(); i<N; i++) {
14561            ProcessMemInfo mi = memInfos.get(i);
14562            if (mi.pss == 0) {
14563                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14564                mi.memtrack = memtrackTmp[0];
14565            }
14566            totalPss += mi.pss;
14567            totalMemtrack += mi.memtrack;
14568        }
14569        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14570            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14571                if (lhs.oomAdj != rhs.oomAdj) {
14572                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14573                }
14574                if (lhs.pss != rhs.pss) {
14575                    return lhs.pss < rhs.pss ? 1 : -1;
14576                }
14577                return 0;
14578            }
14579        });
14580
14581        StringBuilder tag = new StringBuilder(128);
14582        StringBuilder stack = new StringBuilder(128);
14583        tag.append("Low on memory -- ");
14584        appendMemBucket(tag, totalPss, "total", false);
14585        appendMemBucket(stack, totalPss, "total", true);
14586
14587        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14588        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14589        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14590
14591        boolean firstLine = true;
14592        int lastOomAdj = Integer.MIN_VALUE;
14593        long extraNativeRam = 0;
14594        long extraNativeMemtrack = 0;
14595        long cachedPss = 0;
14596        for (int i=0, N=memInfos.size(); i<N; i++) {
14597            ProcessMemInfo mi = memInfos.get(i);
14598
14599            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14600                cachedPss += mi.pss;
14601            }
14602
14603            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14604                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14605                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14606                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14607                if (lastOomAdj != mi.oomAdj) {
14608                    lastOomAdj = mi.oomAdj;
14609                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14610                        tag.append(" / ");
14611                    }
14612                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14613                        if (firstLine) {
14614                            stack.append(":");
14615                            firstLine = false;
14616                        }
14617                        stack.append("\n\t at ");
14618                    } else {
14619                        stack.append("$");
14620                    }
14621                } else {
14622                    tag.append(" ");
14623                    stack.append("$");
14624                }
14625                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14626                    appendMemBucket(tag, mi.pss, mi.name, false);
14627                }
14628                appendMemBucket(stack, mi.pss, mi.name, true);
14629                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14630                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14631                    stack.append("(");
14632                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14633                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14634                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14635                            stack.append(":");
14636                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14637                        }
14638                    }
14639                    stack.append(")");
14640                }
14641            }
14642
14643            appendMemInfo(fullNativeBuilder, mi);
14644            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14645                // The short form only has native processes that are >= 512K.
14646                if (mi.pss >= 512) {
14647                    appendMemInfo(shortNativeBuilder, mi);
14648                } else {
14649                    extraNativeRam += mi.pss;
14650                    extraNativeMemtrack += mi.memtrack;
14651                }
14652            } else {
14653                // Short form has all other details, but if we have collected RAM
14654                // from smaller native processes let's dump a summary of that.
14655                if (extraNativeRam > 0) {
14656                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14657                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14658                    shortNativeBuilder.append('\n');
14659                    extraNativeRam = 0;
14660                }
14661                appendMemInfo(fullJavaBuilder, mi);
14662            }
14663        }
14664
14665        fullJavaBuilder.append("           ");
14666        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14667        fullJavaBuilder.append(" kB: TOTAL");
14668        if (totalMemtrack > 0) {
14669            fullJavaBuilder.append(" (");
14670            fullJavaBuilder.append(totalMemtrack);
14671            fullJavaBuilder.append(" kB memtrack)");
14672        } else {
14673        }
14674        fullJavaBuilder.append("\n");
14675
14676        MemInfoReader memInfo = new MemInfoReader();
14677        memInfo.readMemInfo();
14678        final long[] infos = memInfo.getRawInfo();
14679
14680        StringBuilder memInfoBuilder = new StringBuilder(1024);
14681        Debug.getMemInfo(infos);
14682        memInfoBuilder.append("  MemInfo: ");
14683        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14684        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14685        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14686        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14687        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14688        memInfoBuilder.append("           ");
14689        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14690        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14691        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14692        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14693        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14694            memInfoBuilder.append("  ZRAM: ");
14695            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14696            memInfoBuilder.append(" kB RAM, ");
14697            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14698            memInfoBuilder.append(" kB swap total, ");
14699            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14700            memInfoBuilder.append(" kB swap free\n");
14701        }
14702        final long[] ksm = getKsmInfo();
14703        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14704                || ksm[KSM_VOLATILE] != 0) {
14705            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14706            memInfoBuilder.append(" kB saved from shared ");
14707            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14708            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14709            memInfoBuilder.append(" kB unshared; ");
14710            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14711        }
14712        memInfoBuilder.append("  Free RAM: ");
14713        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14714                + memInfo.getFreeSizeKb());
14715        memInfoBuilder.append(" kB\n");
14716        memInfoBuilder.append("  Used RAM: ");
14717        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14718        memInfoBuilder.append(" kB\n");
14719        memInfoBuilder.append("  Lost RAM: ");
14720        memInfoBuilder.append(memInfo.getTotalSizeKb()
14721                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14722                - memInfo.getKernelUsedSizeKb());
14723        memInfoBuilder.append(" kB\n");
14724        Slog.i(TAG, "Low on memory:");
14725        Slog.i(TAG, shortNativeBuilder.toString());
14726        Slog.i(TAG, fullJavaBuilder.toString());
14727        Slog.i(TAG, memInfoBuilder.toString());
14728
14729        StringBuilder dropBuilder = new StringBuilder(1024);
14730        /*
14731        StringWriter oomSw = new StringWriter();
14732        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14733        StringWriter catSw = new StringWriter();
14734        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14735        String[] emptyArgs = new String[] { };
14736        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14737        oomPw.flush();
14738        String oomString = oomSw.toString();
14739        */
14740        dropBuilder.append("Low on memory:");
14741        dropBuilder.append(stack);
14742        dropBuilder.append('\n');
14743        dropBuilder.append(fullNativeBuilder);
14744        dropBuilder.append(fullJavaBuilder);
14745        dropBuilder.append('\n');
14746        dropBuilder.append(memInfoBuilder);
14747        dropBuilder.append('\n');
14748        /*
14749        dropBuilder.append(oomString);
14750        dropBuilder.append('\n');
14751        */
14752        StringWriter catSw = new StringWriter();
14753        synchronized (ActivityManagerService.this) {
14754            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14755            String[] emptyArgs = new String[] { };
14756            catPw.println();
14757            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14758            catPw.println();
14759            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14760                    false, false, null);
14761            catPw.println();
14762            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14763            catPw.flush();
14764        }
14765        dropBuilder.append(catSw.toString());
14766        addErrorToDropBox("lowmem", null, "system_server", null,
14767                null, tag.toString(), dropBuilder.toString(), null, null);
14768        //Slog.i(TAG, "Sent to dropbox:");
14769        //Slog.i(TAG, dropBuilder.toString());
14770        synchronized (ActivityManagerService.this) {
14771            long now = SystemClock.uptimeMillis();
14772            if (mLastMemUsageReportTime < now) {
14773                mLastMemUsageReportTime = now;
14774            }
14775        }
14776    }
14777
14778    /**
14779     * Searches array of arguments for the specified string
14780     * @param args array of argument strings
14781     * @param value value to search for
14782     * @return true if the value is contained in the array
14783     */
14784    private static boolean scanArgs(String[] args, String value) {
14785        if (args != null) {
14786            for (String arg : args) {
14787                if (value.equals(arg)) {
14788                    return true;
14789                }
14790            }
14791        }
14792        return false;
14793    }
14794
14795    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14796            ContentProviderRecord cpr, boolean always) {
14797        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14798
14799        if (!inLaunching || always) {
14800            synchronized (cpr) {
14801                cpr.launchingApp = null;
14802                cpr.notifyAll();
14803            }
14804            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14805            String names[] = cpr.info.authority.split(";");
14806            for (int j = 0; j < names.length; j++) {
14807                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14808            }
14809        }
14810
14811        for (int i=0; i<cpr.connections.size(); i++) {
14812            ContentProviderConnection conn = cpr.connections.get(i);
14813            if (conn.waiting) {
14814                // If this connection is waiting for the provider, then we don't
14815                // need to mess with its process unless we are always removing
14816                // or for some reason the provider is not currently launching.
14817                if (inLaunching && !always) {
14818                    continue;
14819                }
14820            }
14821            ProcessRecord capp = conn.client;
14822            conn.dead = true;
14823            if (conn.stableCount > 0) {
14824                if (!capp.persistent && capp.thread != null
14825                        && capp.pid != 0
14826                        && capp.pid != MY_PID) {
14827                    capp.kill("depends on provider "
14828                            + cpr.name.flattenToShortString()
14829                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14830                }
14831            } else if (capp.thread != null && conn.provider.provider != null) {
14832                try {
14833                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14834                } catch (RemoteException e) {
14835                }
14836                // In the protocol here, we don't expect the client to correctly
14837                // clean up this connection, we'll just remove it.
14838                cpr.connections.remove(i);
14839                if (conn.client.conProviders.remove(conn)) {
14840                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14841                }
14842            }
14843        }
14844
14845        if (inLaunching && always) {
14846            mLaunchingProviders.remove(cpr);
14847        }
14848        return inLaunching;
14849    }
14850
14851    /**
14852     * Main code for cleaning up a process when it has gone away.  This is
14853     * called both as a result of the process dying, or directly when stopping
14854     * a process when running in single process mode.
14855     *
14856     * @return Returns true if the given process has been restarted, so the
14857     * app that was passed in must remain on the process lists.
14858     */
14859    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14860            boolean restarting, boolean allowRestart, int index) {
14861        if (index >= 0) {
14862            removeLruProcessLocked(app);
14863            ProcessList.remove(app.pid);
14864        }
14865
14866        mProcessesToGc.remove(app);
14867        mPendingPssProcesses.remove(app);
14868
14869        // Dismiss any open dialogs.
14870        if (app.crashDialog != null && !app.forceCrashReport) {
14871            app.crashDialog.dismiss();
14872            app.crashDialog = null;
14873        }
14874        if (app.anrDialog != null) {
14875            app.anrDialog.dismiss();
14876            app.anrDialog = null;
14877        }
14878        if (app.waitDialog != null) {
14879            app.waitDialog.dismiss();
14880            app.waitDialog = null;
14881        }
14882
14883        app.crashing = false;
14884        app.notResponding = false;
14885
14886        app.resetPackageList(mProcessStats);
14887        app.unlinkDeathRecipient();
14888        app.makeInactive(mProcessStats);
14889        app.waitingToKill = null;
14890        app.forcingToForeground = null;
14891        updateProcessForegroundLocked(app, false, false);
14892        app.foregroundActivities = false;
14893        app.hasShownUi = false;
14894        app.treatLikeActivity = false;
14895        app.hasAboveClient = false;
14896        app.hasClientActivities = false;
14897
14898        mServices.killServicesLocked(app, allowRestart);
14899
14900        boolean restart = false;
14901
14902        // Remove published content providers.
14903        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14904            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14905            final boolean always = app.bad || !allowRestart;
14906            if (removeDyingProviderLocked(app, cpr, always) || always) {
14907                // We left the provider in the launching list, need to
14908                // restart it.
14909                restart = true;
14910            }
14911
14912            cpr.provider = null;
14913            cpr.proc = null;
14914        }
14915        app.pubProviders.clear();
14916
14917        // Take care of any launching providers waiting for this process.
14918        if (checkAppInLaunchingProvidersLocked(app, false)) {
14919            restart = true;
14920        }
14921
14922        // Unregister from connected content providers.
14923        if (!app.conProviders.isEmpty()) {
14924            for (int i=0; i<app.conProviders.size(); i++) {
14925                ContentProviderConnection conn = app.conProviders.get(i);
14926                conn.provider.connections.remove(conn);
14927                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14928                        conn.provider.name);
14929            }
14930            app.conProviders.clear();
14931        }
14932
14933        // At this point there may be remaining entries in mLaunchingProviders
14934        // where we were the only one waiting, so they are no longer of use.
14935        // Look for these and clean up if found.
14936        // XXX Commented out for now.  Trying to figure out a way to reproduce
14937        // the actual situation to identify what is actually going on.
14938        if (false) {
14939            for (int i=0; i<mLaunchingProviders.size(); i++) {
14940                ContentProviderRecord cpr = (ContentProviderRecord)
14941                        mLaunchingProviders.get(i);
14942                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14943                    synchronized (cpr) {
14944                        cpr.launchingApp = null;
14945                        cpr.notifyAll();
14946                    }
14947                }
14948            }
14949        }
14950
14951        skipCurrentReceiverLocked(app);
14952
14953        // Unregister any receivers.
14954        for (int i=app.receivers.size()-1; i>=0; i--) {
14955            removeReceiverLocked(app.receivers.valueAt(i));
14956        }
14957        app.receivers.clear();
14958
14959        // If the app is undergoing backup, tell the backup manager about it
14960        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14961            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14962                    + mBackupTarget.appInfo + " died during backup");
14963            try {
14964                IBackupManager bm = IBackupManager.Stub.asInterface(
14965                        ServiceManager.getService(Context.BACKUP_SERVICE));
14966                bm.agentDisconnected(app.info.packageName);
14967            } catch (RemoteException e) {
14968                // can't happen; backup manager is local
14969            }
14970        }
14971
14972        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14973            ProcessChangeItem item = mPendingProcessChanges.get(i);
14974            if (item.pid == app.pid) {
14975                mPendingProcessChanges.remove(i);
14976                mAvailProcessChanges.add(item);
14977            }
14978        }
14979        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14980
14981        // If the caller is restarting this app, then leave it in its
14982        // current lists and let the caller take care of it.
14983        if (restarting) {
14984            return false;
14985        }
14986
14987        if (!app.persistent || app.isolated) {
14988            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14989                    "Removing non-persistent process during cleanup: " + app);
14990            mProcessNames.remove(app.processName, app.uid);
14991            mIsolatedProcesses.remove(app.uid);
14992            if (mHeavyWeightProcess == app) {
14993                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14994                        mHeavyWeightProcess.userId, 0));
14995                mHeavyWeightProcess = null;
14996            }
14997        } else if (!app.removed) {
14998            // This app is persistent, so we need to keep its record around.
14999            // If it is not already on the pending app list, add it there
15000            // and start a new process for it.
15001            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15002                mPersistentStartingProcesses.add(app);
15003                restart = true;
15004            }
15005        }
15006        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15007                "Clean-up removing on hold: " + app);
15008        mProcessesOnHold.remove(app);
15009
15010        if (app == mHomeProcess) {
15011            mHomeProcess = null;
15012        }
15013        if (app == mPreviousProcess) {
15014            mPreviousProcess = null;
15015        }
15016
15017        if (restart && !app.isolated) {
15018            // We have components that still need to be running in the
15019            // process, so re-launch it.
15020            if (index < 0) {
15021                ProcessList.remove(app.pid);
15022            }
15023            mProcessNames.put(app.processName, app.uid, app);
15024            startProcessLocked(app, "restart", app.processName);
15025            return true;
15026        } else if (app.pid > 0 && app.pid != MY_PID) {
15027            // Goodbye!
15028            boolean removed;
15029            synchronized (mPidsSelfLocked) {
15030                mPidsSelfLocked.remove(app.pid);
15031                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15032            }
15033            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15034            if (app.isolated) {
15035                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15036            }
15037            app.setPid(0);
15038        }
15039        return false;
15040    }
15041
15042    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15043        // Look through the content providers we are waiting to have launched,
15044        // and if any run in this process then either schedule a restart of
15045        // the process or kill the client waiting for it if this process has
15046        // gone bad.
15047        int NL = mLaunchingProviders.size();
15048        boolean restart = false;
15049        for (int i=0; i<NL; i++) {
15050            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15051            if (cpr.launchingApp == app) {
15052                if (!alwaysBad && !app.bad) {
15053                    restart = true;
15054                } else {
15055                    removeDyingProviderLocked(app, cpr, true);
15056                    // cpr should have been removed from mLaunchingProviders
15057                    NL = mLaunchingProviders.size();
15058                    i--;
15059                }
15060            }
15061        }
15062        return restart;
15063    }
15064
15065    // =========================================================
15066    // SERVICES
15067    // =========================================================
15068
15069    @Override
15070    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15071            int flags) {
15072        enforceNotIsolatedCaller("getServices");
15073        synchronized (this) {
15074            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15075        }
15076    }
15077
15078    @Override
15079    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15080        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15081        synchronized (this) {
15082            return mServices.getRunningServiceControlPanelLocked(name);
15083        }
15084    }
15085
15086    @Override
15087    public ComponentName startService(IApplicationThread caller, Intent service,
15088            String resolvedType, int userId) {
15089        enforceNotIsolatedCaller("startService");
15090        // Refuse possible leaked file descriptors
15091        if (service != null && service.hasFileDescriptors() == true) {
15092            throw new IllegalArgumentException("File descriptors passed in Intent");
15093        }
15094
15095        if (DEBUG_SERVICE)
15096            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15097        synchronized(this) {
15098            final int callingPid = Binder.getCallingPid();
15099            final int callingUid = Binder.getCallingUid();
15100            final long origId = Binder.clearCallingIdentity();
15101            ComponentName res = mServices.startServiceLocked(caller, service,
15102                    resolvedType, callingPid, callingUid, userId);
15103            Binder.restoreCallingIdentity(origId);
15104            return res;
15105        }
15106    }
15107
15108    ComponentName startServiceInPackage(int uid,
15109            Intent service, String resolvedType, int userId) {
15110        synchronized(this) {
15111            if (DEBUG_SERVICE)
15112                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15113            final long origId = Binder.clearCallingIdentity();
15114            ComponentName res = mServices.startServiceLocked(null, service,
15115                    resolvedType, -1, uid, userId);
15116            Binder.restoreCallingIdentity(origId);
15117            return res;
15118        }
15119    }
15120
15121    @Override
15122    public int stopService(IApplicationThread caller, Intent service,
15123            String resolvedType, int userId) {
15124        enforceNotIsolatedCaller("stopService");
15125        // Refuse possible leaked file descriptors
15126        if (service != null && service.hasFileDescriptors() == true) {
15127            throw new IllegalArgumentException("File descriptors passed in Intent");
15128        }
15129
15130        synchronized(this) {
15131            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15132        }
15133    }
15134
15135    @Override
15136    public IBinder peekService(Intent service, String resolvedType) {
15137        enforceNotIsolatedCaller("peekService");
15138        // Refuse possible leaked file descriptors
15139        if (service != null && service.hasFileDescriptors() == true) {
15140            throw new IllegalArgumentException("File descriptors passed in Intent");
15141        }
15142        synchronized(this) {
15143            return mServices.peekServiceLocked(service, resolvedType);
15144        }
15145    }
15146
15147    @Override
15148    public boolean stopServiceToken(ComponentName className, IBinder token,
15149            int startId) {
15150        synchronized(this) {
15151            return mServices.stopServiceTokenLocked(className, token, startId);
15152        }
15153    }
15154
15155    @Override
15156    public void setServiceForeground(ComponentName className, IBinder token,
15157            int id, Notification notification, boolean removeNotification) {
15158        synchronized(this) {
15159            mServices.setServiceForegroundLocked(className, token, id, notification,
15160                    removeNotification);
15161        }
15162    }
15163
15164    @Override
15165    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15166            boolean requireFull, String name, String callerPackage) {
15167        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15168                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15169    }
15170
15171    int unsafeConvertIncomingUser(int userId) {
15172        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15173                ? mCurrentUserId : userId;
15174    }
15175
15176    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15177            int allowMode, String name, String callerPackage) {
15178        final int callingUserId = UserHandle.getUserId(callingUid);
15179        if (callingUserId == userId) {
15180            return userId;
15181        }
15182
15183        // Note that we may be accessing mCurrentUserId outside of a lock...
15184        // shouldn't be a big deal, if this is being called outside
15185        // of a locked context there is intrinsically a race with
15186        // the value the caller will receive and someone else changing it.
15187        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15188        // we will switch to the calling user if access to the current user fails.
15189        int targetUserId = unsafeConvertIncomingUser(userId);
15190
15191        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15192            final boolean allow;
15193            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15194                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15195                // If the caller has this permission, they always pass go.  And collect $200.
15196                allow = true;
15197            } else if (allowMode == ALLOW_FULL_ONLY) {
15198                // We require full access, sucks to be you.
15199                allow = false;
15200            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15201                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15202                // If the caller does not have either permission, they are always doomed.
15203                allow = false;
15204            } else if (allowMode == ALLOW_NON_FULL) {
15205                // We are blanket allowing non-full access, you lucky caller!
15206                allow = true;
15207            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15208                // We may or may not allow this depending on whether the two users are
15209                // in the same profile.
15210                synchronized (mUserProfileGroupIdsSelfLocked) {
15211                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15212                            UserInfo.NO_PROFILE_GROUP_ID);
15213                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15214                            UserInfo.NO_PROFILE_GROUP_ID);
15215                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15216                            && callingProfile == targetProfile;
15217                }
15218            } else {
15219                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15220            }
15221            if (!allow) {
15222                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15223                    // In this case, they would like to just execute as their
15224                    // owner user instead of failing.
15225                    targetUserId = callingUserId;
15226                } else {
15227                    StringBuilder builder = new StringBuilder(128);
15228                    builder.append("Permission Denial: ");
15229                    builder.append(name);
15230                    if (callerPackage != null) {
15231                        builder.append(" from ");
15232                        builder.append(callerPackage);
15233                    }
15234                    builder.append(" asks to run as user ");
15235                    builder.append(userId);
15236                    builder.append(" but is calling from user ");
15237                    builder.append(UserHandle.getUserId(callingUid));
15238                    builder.append("; this requires ");
15239                    builder.append(INTERACT_ACROSS_USERS_FULL);
15240                    if (allowMode != ALLOW_FULL_ONLY) {
15241                        builder.append(" or ");
15242                        builder.append(INTERACT_ACROSS_USERS);
15243                    }
15244                    String msg = builder.toString();
15245                    Slog.w(TAG, msg);
15246                    throw new SecurityException(msg);
15247                }
15248            }
15249        }
15250        if (!allowAll && targetUserId < 0) {
15251            throw new IllegalArgumentException(
15252                    "Call does not support special user #" + targetUserId);
15253        }
15254        // Check shell permission
15255        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15256            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15257                    targetUserId)) {
15258                throw new SecurityException("Shell does not have permission to access user "
15259                        + targetUserId + "\n " + Debug.getCallers(3));
15260            }
15261        }
15262        return targetUserId;
15263    }
15264
15265    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15266            String className, int flags) {
15267        boolean result = false;
15268        // For apps that don't have pre-defined UIDs, check for permission
15269        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15270            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15271                if (ActivityManager.checkUidPermission(
15272                        INTERACT_ACROSS_USERS,
15273                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15274                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15275                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15276                            + " requests FLAG_SINGLE_USER, but app does not hold "
15277                            + INTERACT_ACROSS_USERS;
15278                    Slog.w(TAG, msg);
15279                    throw new SecurityException(msg);
15280                }
15281                // Permission passed
15282                result = true;
15283            }
15284        } else if ("system".equals(componentProcessName)) {
15285            result = true;
15286        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15287            // Phone app and persistent apps are allowed to export singleuser providers.
15288            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15289                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15290        }
15291        if (DEBUG_MU) {
15292            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15293                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15294        }
15295        return result;
15296    }
15297
15298    /**
15299     * Checks to see if the caller is in the same app as the singleton
15300     * component, or the component is in a special app. It allows special apps
15301     * to export singleton components but prevents exporting singleton
15302     * components for regular apps.
15303     */
15304    boolean isValidSingletonCall(int callingUid, int componentUid) {
15305        int componentAppId = UserHandle.getAppId(componentUid);
15306        return UserHandle.isSameApp(callingUid, componentUid)
15307                || componentAppId == Process.SYSTEM_UID
15308                || componentAppId == Process.PHONE_UID
15309                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15310                        == PackageManager.PERMISSION_GRANTED;
15311    }
15312
15313    public int bindService(IApplicationThread caller, IBinder token,
15314            Intent service, String resolvedType,
15315            IServiceConnection connection, int flags, int userId) {
15316        enforceNotIsolatedCaller("bindService");
15317
15318        // Refuse possible leaked file descriptors
15319        if (service != null && service.hasFileDescriptors() == true) {
15320            throw new IllegalArgumentException("File descriptors passed in Intent");
15321        }
15322
15323        synchronized(this) {
15324            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15325                    connection, flags, userId);
15326        }
15327    }
15328
15329    public boolean unbindService(IServiceConnection connection) {
15330        synchronized (this) {
15331            return mServices.unbindServiceLocked(connection);
15332        }
15333    }
15334
15335    public void publishService(IBinder token, Intent intent, IBinder service) {
15336        // Refuse possible leaked file descriptors
15337        if (intent != null && intent.hasFileDescriptors() == true) {
15338            throw new IllegalArgumentException("File descriptors passed in Intent");
15339        }
15340
15341        synchronized(this) {
15342            if (!(token instanceof ServiceRecord)) {
15343                throw new IllegalArgumentException("Invalid service token");
15344            }
15345            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15346        }
15347    }
15348
15349    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15350        // Refuse possible leaked file descriptors
15351        if (intent != null && intent.hasFileDescriptors() == true) {
15352            throw new IllegalArgumentException("File descriptors passed in Intent");
15353        }
15354
15355        synchronized(this) {
15356            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15357        }
15358    }
15359
15360    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15361        synchronized(this) {
15362            if (!(token instanceof ServiceRecord)) {
15363                throw new IllegalArgumentException("Invalid service token");
15364            }
15365            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15366        }
15367    }
15368
15369    // =========================================================
15370    // BACKUP AND RESTORE
15371    // =========================================================
15372
15373    // Cause the target app to be launched if necessary and its backup agent
15374    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15375    // activity manager to announce its creation.
15376    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15377        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15378        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15379
15380        synchronized(this) {
15381            // !!! TODO: currently no check here that we're already bound
15382            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15383            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15384            synchronized (stats) {
15385                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15386            }
15387
15388            // Backup agent is now in use, its package can't be stopped.
15389            try {
15390                AppGlobals.getPackageManager().setPackageStoppedState(
15391                        app.packageName, false, UserHandle.getUserId(app.uid));
15392            } catch (RemoteException e) {
15393            } catch (IllegalArgumentException e) {
15394                Slog.w(TAG, "Failed trying to unstop package "
15395                        + app.packageName + ": " + e);
15396            }
15397
15398            BackupRecord r = new BackupRecord(ss, app, backupMode);
15399            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15400                    ? new ComponentName(app.packageName, app.backupAgentName)
15401                    : new ComponentName("android", "FullBackupAgent");
15402            // startProcessLocked() returns existing proc's record if it's already running
15403            ProcessRecord proc = startProcessLocked(app.processName, app,
15404                    false, 0, "backup", hostingName, false, false, false);
15405            if (proc == null) {
15406                Slog.e(TAG, "Unable to start backup agent process " + r);
15407                return false;
15408            }
15409
15410            r.app = proc;
15411            mBackupTarget = r;
15412            mBackupAppName = app.packageName;
15413
15414            // Try not to kill the process during backup
15415            updateOomAdjLocked(proc);
15416
15417            // If the process is already attached, schedule the creation of the backup agent now.
15418            // If it is not yet live, this will be done when it attaches to the framework.
15419            if (proc.thread != null) {
15420                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15421                try {
15422                    proc.thread.scheduleCreateBackupAgent(app,
15423                            compatibilityInfoForPackageLocked(app), backupMode);
15424                } catch (RemoteException e) {
15425                    // Will time out on the backup manager side
15426                }
15427            } else {
15428                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15429            }
15430            // Invariants: at this point, the target app process exists and the application
15431            // is either already running or in the process of coming up.  mBackupTarget and
15432            // mBackupAppName describe the app, so that when it binds back to the AM we
15433            // know that it's scheduled for a backup-agent operation.
15434        }
15435
15436        return true;
15437    }
15438
15439    @Override
15440    public void clearPendingBackup() {
15441        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15442        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15443
15444        synchronized (this) {
15445            mBackupTarget = null;
15446            mBackupAppName = null;
15447        }
15448    }
15449
15450    // A backup agent has just come up
15451    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15452        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15453                + " = " + agent);
15454
15455        synchronized(this) {
15456            if (!agentPackageName.equals(mBackupAppName)) {
15457                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15458                return;
15459            }
15460        }
15461
15462        long oldIdent = Binder.clearCallingIdentity();
15463        try {
15464            IBackupManager bm = IBackupManager.Stub.asInterface(
15465                    ServiceManager.getService(Context.BACKUP_SERVICE));
15466            bm.agentConnected(agentPackageName, agent);
15467        } catch (RemoteException e) {
15468            // can't happen; the backup manager service is local
15469        } catch (Exception e) {
15470            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15471            e.printStackTrace();
15472        } finally {
15473            Binder.restoreCallingIdentity(oldIdent);
15474        }
15475    }
15476
15477    // done with this agent
15478    public void unbindBackupAgent(ApplicationInfo appInfo) {
15479        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15480        if (appInfo == null) {
15481            Slog.w(TAG, "unbind backup agent for null app");
15482            return;
15483        }
15484
15485        synchronized(this) {
15486            try {
15487                if (mBackupAppName == null) {
15488                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15489                    return;
15490                }
15491
15492                if (!mBackupAppName.equals(appInfo.packageName)) {
15493                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15494                    return;
15495                }
15496
15497                // Not backing this app up any more; reset its OOM adjustment
15498                final ProcessRecord proc = mBackupTarget.app;
15499                updateOomAdjLocked(proc);
15500
15501                // If the app crashed during backup, 'thread' will be null here
15502                if (proc.thread != null) {
15503                    try {
15504                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15505                                compatibilityInfoForPackageLocked(appInfo));
15506                    } catch (Exception e) {
15507                        Slog.e(TAG, "Exception when unbinding backup agent:");
15508                        e.printStackTrace();
15509                    }
15510                }
15511            } finally {
15512                mBackupTarget = null;
15513                mBackupAppName = null;
15514            }
15515        }
15516    }
15517    // =========================================================
15518    // BROADCASTS
15519    // =========================================================
15520
15521    private final List getStickiesLocked(String action, IntentFilter filter,
15522            List cur, int userId) {
15523        final ContentResolver resolver = mContext.getContentResolver();
15524        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15525        if (stickies == null) {
15526            return cur;
15527        }
15528        final ArrayList<Intent> list = stickies.get(action);
15529        if (list == null) {
15530            return cur;
15531        }
15532        int N = list.size();
15533        for (int i=0; i<N; i++) {
15534            Intent intent = list.get(i);
15535            if (filter.match(resolver, intent, true, TAG) >= 0) {
15536                if (cur == null) {
15537                    cur = new ArrayList<Intent>();
15538                }
15539                cur.add(intent);
15540            }
15541        }
15542        return cur;
15543    }
15544
15545    boolean isPendingBroadcastProcessLocked(int pid) {
15546        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15547                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15548    }
15549
15550    void skipPendingBroadcastLocked(int pid) {
15551            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15552            for (BroadcastQueue queue : mBroadcastQueues) {
15553                queue.skipPendingBroadcastLocked(pid);
15554            }
15555    }
15556
15557    // The app just attached; send any pending broadcasts that it should receive
15558    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15559        boolean didSomething = false;
15560        for (BroadcastQueue queue : mBroadcastQueues) {
15561            didSomething |= queue.sendPendingBroadcastsLocked(app);
15562        }
15563        return didSomething;
15564    }
15565
15566    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15567            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15568        enforceNotIsolatedCaller("registerReceiver");
15569        int callingUid;
15570        int callingPid;
15571        synchronized(this) {
15572            ProcessRecord callerApp = null;
15573            if (caller != null) {
15574                callerApp = getRecordForAppLocked(caller);
15575                if (callerApp == null) {
15576                    throw new SecurityException(
15577                            "Unable to find app for caller " + caller
15578                            + " (pid=" + Binder.getCallingPid()
15579                            + ") when registering receiver " + receiver);
15580                }
15581                if (callerApp.info.uid != Process.SYSTEM_UID &&
15582                        !callerApp.pkgList.containsKey(callerPackage) &&
15583                        !"android".equals(callerPackage)) {
15584                    throw new SecurityException("Given caller package " + callerPackage
15585                            + " is not running in process " + callerApp);
15586                }
15587                callingUid = callerApp.info.uid;
15588                callingPid = callerApp.pid;
15589            } else {
15590                callerPackage = null;
15591                callingUid = Binder.getCallingUid();
15592                callingPid = Binder.getCallingPid();
15593            }
15594
15595            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15596                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15597
15598            List allSticky = null;
15599
15600            // Look for any matching sticky broadcasts...
15601            Iterator actions = filter.actionsIterator();
15602            if (actions != null) {
15603                while (actions.hasNext()) {
15604                    String action = (String)actions.next();
15605                    allSticky = getStickiesLocked(action, filter, allSticky,
15606                            UserHandle.USER_ALL);
15607                    allSticky = getStickiesLocked(action, filter, allSticky,
15608                            UserHandle.getUserId(callingUid));
15609                }
15610            } else {
15611                allSticky = getStickiesLocked(null, filter, allSticky,
15612                        UserHandle.USER_ALL);
15613                allSticky = getStickiesLocked(null, filter, allSticky,
15614                        UserHandle.getUserId(callingUid));
15615            }
15616
15617            // The first sticky in the list is returned directly back to
15618            // the client.
15619            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15620
15621            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15622                    + ": " + sticky);
15623
15624            if (receiver == null) {
15625                return sticky;
15626            }
15627
15628            ReceiverList rl
15629                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15630            if (rl == null) {
15631                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15632                        userId, receiver);
15633                if (rl.app != null) {
15634                    rl.app.receivers.add(rl);
15635                } else {
15636                    try {
15637                        receiver.asBinder().linkToDeath(rl, 0);
15638                    } catch (RemoteException e) {
15639                        return sticky;
15640                    }
15641                    rl.linkedToDeath = true;
15642                }
15643                mRegisteredReceivers.put(receiver.asBinder(), rl);
15644            } else if (rl.uid != callingUid) {
15645                throw new IllegalArgumentException(
15646                        "Receiver requested to register for uid " + callingUid
15647                        + " was previously registered for uid " + rl.uid);
15648            } else if (rl.pid != callingPid) {
15649                throw new IllegalArgumentException(
15650                        "Receiver requested to register for pid " + callingPid
15651                        + " was previously registered for pid " + rl.pid);
15652            } else if (rl.userId != userId) {
15653                throw new IllegalArgumentException(
15654                        "Receiver requested to register for user " + userId
15655                        + " was previously registered for user " + rl.userId);
15656            }
15657            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15658                    permission, callingUid, userId);
15659            rl.add(bf);
15660            if (!bf.debugCheck()) {
15661                Slog.w(TAG, "==> For Dynamic broadast");
15662            }
15663            mReceiverResolver.addFilter(bf);
15664
15665            // Enqueue broadcasts for all existing stickies that match
15666            // this filter.
15667            if (allSticky != null) {
15668                ArrayList receivers = new ArrayList();
15669                receivers.add(bf);
15670
15671                int N = allSticky.size();
15672                for (int i=0; i<N; i++) {
15673                    Intent intent = (Intent)allSticky.get(i);
15674                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15675                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15676                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15677                            null, null, false, true, true, -1);
15678                    queue.enqueueParallelBroadcastLocked(r);
15679                    queue.scheduleBroadcastsLocked();
15680                }
15681            }
15682
15683            return sticky;
15684        }
15685    }
15686
15687    public void unregisterReceiver(IIntentReceiver receiver) {
15688        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15689
15690        final long origId = Binder.clearCallingIdentity();
15691        try {
15692            boolean doTrim = false;
15693
15694            synchronized(this) {
15695                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15696                if (rl != null) {
15697                    if (rl.curBroadcast != null) {
15698                        BroadcastRecord r = rl.curBroadcast;
15699                        final boolean doNext = finishReceiverLocked(
15700                                receiver.asBinder(), r.resultCode, r.resultData,
15701                                r.resultExtras, r.resultAbort);
15702                        if (doNext) {
15703                            doTrim = true;
15704                            r.queue.processNextBroadcast(false);
15705                        }
15706                    }
15707
15708                    if (rl.app != null) {
15709                        rl.app.receivers.remove(rl);
15710                    }
15711                    removeReceiverLocked(rl);
15712                    if (rl.linkedToDeath) {
15713                        rl.linkedToDeath = false;
15714                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15715                    }
15716                }
15717            }
15718
15719            // If we actually concluded any broadcasts, we might now be able
15720            // to trim the recipients' apps from our working set
15721            if (doTrim) {
15722                trimApplications();
15723                return;
15724            }
15725
15726        } finally {
15727            Binder.restoreCallingIdentity(origId);
15728        }
15729    }
15730
15731    void removeReceiverLocked(ReceiverList rl) {
15732        mRegisteredReceivers.remove(rl.receiver.asBinder());
15733        int N = rl.size();
15734        for (int i=0; i<N; i++) {
15735            mReceiverResolver.removeFilter(rl.get(i));
15736        }
15737    }
15738
15739    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15740        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15741            ProcessRecord r = mLruProcesses.get(i);
15742            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15743                try {
15744                    r.thread.dispatchPackageBroadcast(cmd, packages);
15745                } catch (RemoteException ex) {
15746                }
15747            }
15748        }
15749    }
15750
15751    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15752            int callingUid, int[] users) {
15753        List<ResolveInfo> receivers = null;
15754        try {
15755            HashSet<ComponentName> singleUserReceivers = null;
15756            boolean scannedFirstReceivers = false;
15757            for (int user : users) {
15758                // Skip users that have Shell restrictions
15759                if (callingUid == Process.SHELL_UID
15760                        && getUserManagerLocked().hasUserRestriction(
15761                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15762                    continue;
15763                }
15764                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15765                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15766                if (user != 0 && newReceivers != null) {
15767                    // If this is not the primary user, we need to check for
15768                    // any receivers that should be filtered out.
15769                    for (int i=0; i<newReceivers.size(); i++) {
15770                        ResolveInfo ri = newReceivers.get(i);
15771                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15772                            newReceivers.remove(i);
15773                            i--;
15774                        }
15775                    }
15776                }
15777                if (newReceivers != null && newReceivers.size() == 0) {
15778                    newReceivers = null;
15779                }
15780                if (receivers == null) {
15781                    receivers = newReceivers;
15782                } else if (newReceivers != null) {
15783                    // We need to concatenate the additional receivers
15784                    // found with what we have do far.  This would be easy,
15785                    // but we also need to de-dup any receivers that are
15786                    // singleUser.
15787                    if (!scannedFirstReceivers) {
15788                        // Collect any single user receivers we had already retrieved.
15789                        scannedFirstReceivers = true;
15790                        for (int i=0; i<receivers.size(); i++) {
15791                            ResolveInfo ri = receivers.get(i);
15792                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15793                                ComponentName cn = new ComponentName(
15794                                        ri.activityInfo.packageName, ri.activityInfo.name);
15795                                if (singleUserReceivers == null) {
15796                                    singleUserReceivers = new HashSet<ComponentName>();
15797                                }
15798                                singleUserReceivers.add(cn);
15799                            }
15800                        }
15801                    }
15802                    // Add the new results to the existing results, tracking
15803                    // and de-dupping single user receivers.
15804                    for (int i=0; i<newReceivers.size(); i++) {
15805                        ResolveInfo ri = newReceivers.get(i);
15806                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15807                            ComponentName cn = new ComponentName(
15808                                    ri.activityInfo.packageName, ri.activityInfo.name);
15809                            if (singleUserReceivers == null) {
15810                                singleUserReceivers = new HashSet<ComponentName>();
15811                            }
15812                            if (!singleUserReceivers.contains(cn)) {
15813                                singleUserReceivers.add(cn);
15814                                receivers.add(ri);
15815                            }
15816                        } else {
15817                            receivers.add(ri);
15818                        }
15819                    }
15820                }
15821            }
15822        } catch (RemoteException ex) {
15823            // pm is in same process, this will never happen.
15824        }
15825        return receivers;
15826    }
15827
15828    private final int broadcastIntentLocked(ProcessRecord callerApp,
15829            String callerPackage, Intent intent, String resolvedType,
15830            IIntentReceiver resultTo, int resultCode, String resultData,
15831            Bundle map, String requiredPermission, int appOp,
15832            boolean ordered, boolean sticky, int callingPid, int callingUid,
15833            int userId) {
15834        intent = new Intent(intent);
15835
15836        // By default broadcasts do not go to stopped apps.
15837        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15838
15839        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15840            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15841            + " ordered=" + ordered + " userid=" + userId);
15842        if ((resultTo != null) && !ordered) {
15843            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15844        }
15845
15846        userId = handleIncomingUser(callingPid, callingUid, userId,
15847                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15848
15849        // Make sure that the user who is receiving this broadcast is running.
15850        // If not, we will just skip it. Make an exception for shutdown broadcasts
15851        // and upgrade steps.
15852
15853        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15854            if ((callingUid != Process.SYSTEM_UID
15855                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15856                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15857                Slog.w(TAG, "Skipping broadcast of " + intent
15858                        + ": user " + userId + " is stopped");
15859                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15860            }
15861        }
15862
15863        /*
15864         * Prevent non-system code (defined here to be non-persistent
15865         * processes) from sending protected broadcasts.
15866         */
15867        int callingAppId = UserHandle.getAppId(callingUid);
15868        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15869            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15870            || callingAppId == Process.NFC_UID || callingUid == 0) {
15871            // Always okay.
15872        } else if (callerApp == null || !callerApp.persistent) {
15873            try {
15874                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15875                        intent.getAction())) {
15876                    String msg = "Permission Denial: not allowed to send broadcast "
15877                            + intent.getAction() + " from pid="
15878                            + callingPid + ", uid=" + callingUid;
15879                    Slog.w(TAG, msg);
15880                    throw new SecurityException(msg);
15881                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15882                    // Special case for compatibility: we don't want apps to send this,
15883                    // but historically it has not been protected and apps may be using it
15884                    // to poke their own app widget.  So, instead of making it protected,
15885                    // just limit it to the caller.
15886                    if (callerApp == null) {
15887                        String msg = "Permission Denial: not allowed to send broadcast "
15888                                + intent.getAction() + " from unknown caller.";
15889                        Slog.w(TAG, msg);
15890                        throw new SecurityException(msg);
15891                    } else if (intent.getComponent() != null) {
15892                        // They are good enough to send to an explicit component...  verify
15893                        // it is being sent to the calling app.
15894                        if (!intent.getComponent().getPackageName().equals(
15895                                callerApp.info.packageName)) {
15896                            String msg = "Permission Denial: not allowed to send broadcast "
15897                                    + intent.getAction() + " to "
15898                                    + intent.getComponent().getPackageName() + " from "
15899                                    + callerApp.info.packageName;
15900                            Slog.w(TAG, msg);
15901                            throw new SecurityException(msg);
15902                        }
15903                    } else {
15904                        // Limit broadcast to their own package.
15905                        intent.setPackage(callerApp.info.packageName);
15906                    }
15907                }
15908            } catch (RemoteException e) {
15909                Slog.w(TAG, "Remote exception", e);
15910                return ActivityManager.BROADCAST_SUCCESS;
15911            }
15912        }
15913
15914        final String action = intent.getAction();
15915        if (action != null) {
15916            switch (action) {
15917                case Intent.ACTION_UID_REMOVED:
15918                case Intent.ACTION_PACKAGE_REMOVED:
15919                case Intent.ACTION_PACKAGE_CHANGED:
15920                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15921                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15922                    // Handle special intents: if this broadcast is from the package
15923                    // manager about a package being removed, we need to remove all of
15924                    // its activities from the history stack.
15925                    if (checkComponentPermission(
15926                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15927                            callingPid, callingUid, -1, true)
15928                            != PackageManager.PERMISSION_GRANTED) {
15929                        String msg = "Permission Denial: " + intent.getAction()
15930                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15931                                + ", uid=" + callingUid + ")"
15932                                + " requires "
15933                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15934                        Slog.w(TAG, msg);
15935                        throw new SecurityException(msg);
15936                    }
15937                    switch (action) {
15938                        case Intent.ACTION_UID_REMOVED:
15939                            final Bundle intentExtras = intent.getExtras();
15940                            final int uid = intentExtras != null
15941                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15942                            if (uid >= 0) {
15943                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15944                                synchronized (bs) {
15945                                    bs.removeUidStatsLocked(uid);
15946                                }
15947                                mAppOpsService.uidRemoved(uid);
15948                            }
15949                            break;
15950                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15951                            // If resources are unavailable just force stop all those packages
15952                            // and flush the attribute cache as well.
15953                            String list[] =
15954                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15955                            if (list != null && list.length > 0) {
15956                                for (int i = 0; i < list.length; i++) {
15957                                    forceStopPackageLocked(list[i], -1, false, true, true,
15958                                            false, false, userId, "storage unmount");
15959                                }
15960                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15961                                sendPackageBroadcastLocked(
15962                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15963                                        userId);
15964                            }
15965                            break;
15966                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15967                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15968                            break;
15969                        case Intent.ACTION_PACKAGE_REMOVED:
15970                        case Intent.ACTION_PACKAGE_CHANGED:
15971                            Uri data = intent.getData();
15972                            String ssp;
15973                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15974                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15975                                boolean fullUninstall = removed &&
15976                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15977                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15978                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15979                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15980                                            false, true, true, false, fullUninstall, userId,
15981                                            removed ? "pkg removed" : "pkg changed");
15982                                }
15983                                if (removed) {
15984                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15985                                            new String[] {ssp}, userId);
15986                                    if (fullUninstall) {
15987                                        mAppOpsService.packageRemoved(
15988                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15989
15990                                        // Remove all permissions granted from/to this package
15991                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15992
15993                                        removeTasksByPackageNameLocked(ssp, userId);
15994                                    }
15995                                } else {
15996                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15997                                    if (userId == UserHandle.USER_OWNER) {
15998                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15999                                    }
16000                                }
16001                            }
16002                            break;
16003                    }
16004                    break;
16005                case Intent.ACTION_PACKAGE_ADDED:
16006                    // Special case for adding a package: by default turn on compatibility mode.
16007                    Uri data = intent.getData();
16008                    String ssp;
16009                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16010                        final boolean replacing =
16011                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16012                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16013
16014                        if (replacing) {
16015                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16016                        }
16017                        if (userId == UserHandle.USER_OWNER) {
16018                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16019                        }
16020                    }
16021                    break;
16022                case Intent.ACTION_TIMEZONE_CHANGED:
16023                    // If this is the time zone changed action, queue up a message that will reset
16024                    // the timezone of all currently running processes. This message will get
16025                    // queued up before the broadcast happens.
16026                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16027                    break;
16028                case Intent.ACTION_TIME_CHANGED:
16029                    // If the user set the time, let all running processes know.
16030                    final int is24Hour =
16031                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16032                                    : 0;
16033                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16034                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16035                    synchronized (stats) {
16036                        stats.noteCurrentTimeChangedLocked();
16037                    }
16038                    break;
16039                case Intent.ACTION_CLEAR_DNS_CACHE:
16040                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16041                    break;
16042                case Proxy.PROXY_CHANGE_ACTION:
16043                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16044                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16045                    break;
16046            }
16047        }
16048
16049        // Add to the sticky list if requested.
16050        if (sticky) {
16051            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16052                    callingPid, callingUid)
16053                    != PackageManager.PERMISSION_GRANTED) {
16054                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16055                        + callingPid + ", uid=" + callingUid
16056                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16057                Slog.w(TAG, msg);
16058                throw new SecurityException(msg);
16059            }
16060            if (requiredPermission != null) {
16061                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16062                        + " and enforce permission " + requiredPermission);
16063                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16064            }
16065            if (intent.getComponent() != null) {
16066                throw new SecurityException(
16067                        "Sticky broadcasts can't target a specific component");
16068            }
16069            // We use userId directly here, since the "all" target is maintained
16070            // as a separate set of sticky broadcasts.
16071            if (userId != UserHandle.USER_ALL) {
16072                // But first, if this is not a broadcast to all users, then
16073                // make sure it doesn't conflict with an existing broadcast to
16074                // all users.
16075                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16076                        UserHandle.USER_ALL);
16077                if (stickies != null) {
16078                    ArrayList<Intent> list = stickies.get(intent.getAction());
16079                    if (list != null) {
16080                        int N = list.size();
16081                        int i;
16082                        for (i=0; i<N; i++) {
16083                            if (intent.filterEquals(list.get(i))) {
16084                                throw new IllegalArgumentException(
16085                                        "Sticky broadcast " + intent + " for user "
16086                                        + userId + " conflicts with existing global broadcast");
16087                            }
16088                        }
16089                    }
16090                }
16091            }
16092            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16093            if (stickies == null) {
16094                stickies = new ArrayMap<String, ArrayList<Intent>>();
16095                mStickyBroadcasts.put(userId, stickies);
16096            }
16097            ArrayList<Intent> list = stickies.get(intent.getAction());
16098            if (list == null) {
16099                list = new ArrayList<Intent>();
16100                stickies.put(intent.getAction(), list);
16101            }
16102            int N = list.size();
16103            int i;
16104            for (i=0; i<N; i++) {
16105                if (intent.filterEquals(list.get(i))) {
16106                    // This sticky already exists, replace it.
16107                    list.set(i, new Intent(intent));
16108                    break;
16109                }
16110            }
16111            if (i >= N) {
16112                list.add(new Intent(intent));
16113            }
16114        }
16115
16116        int[] users;
16117        if (userId == UserHandle.USER_ALL) {
16118            // Caller wants broadcast to go to all started users.
16119            users = mStartedUserArray;
16120        } else {
16121            // Caller wants broadcast to go to one specific user.
16122            users = new int[] {userId};
16123        }
16124
16125        // Figure out who all will receive this broadcast.
16126        List receivers = null;
16127        List<BroadcastFilter> registeredReceivers = null;
16128        // Need to resolve the intent to interested receivers...
16129        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16130                 == 0) {
16131            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16132        }
16133        if (intent.getComponent() == null) {
16134            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16135                // Query one target user at a time, excluding shell-restricted users
16136                UserManagerService ums = getUserManagerLocked();
16137                for (int i = 0; i < users.length; i++) {
16138                    if (ums.hasUserRestriction(
16139                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16140                        continue;
16141                    }
16142                    List<BroadcastFilter> registeredReceiversForUser =
16143                            mReceiverResolver.queryIntent(intent,
16144                                    resolvedType, false, users[i]);
16145                    if (registeredReceivers == null) {
16146                        registeredReceivers = registeredReceiversForUser;
16147                    } else if (registeredReceiversForUser != null) {
16148                        registeredReceivers.addAll(registeredReceiversForUser);
16149                    }
16150                }
16151            } else {
16152                registeredReceivers = mReceiverResolver.queryIntent(intent,
16153                        resolvedType, false, userId);
16154            }
16155        }
16156
16157        final boolean replacePending =
16158                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16159
16160        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16161                + " replacePending=" + replacePending);
16162
16163        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16164        if (!ordered && NR > 0) {
16165            // If we are not serializing this broadcast, then send the
16166            // registered receivers separately so they don't wait for the
16167            // components to be launched.
16168            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16169            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16170                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16171                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16172                    ordered, sticky, false, userId);
16173            if (DEBUG_BROADCAST) Slog.v(
16174                    TAG, "Enqueueing parallel broadcast " + r);
16175            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16176            if (!replaced) {
16177                queue.enqueueParallelBroadcastLocked(r);
16178                queue.scheduleBroadcastsLocked();
16179            }
16180            registeredReceivers = null;
16181            NR = 0;
16182        }
16183
16184        // Merge into one list.
16185        int ir = 0;
16186        if (receivers != null) {
16187            // A special case for PACKAGE_ADDED: do not allow the package
16188            // being added to see this broadcast.  This prevents them from
16189            // using this as a back door to get run as soon as they are
16190            // installed.  Maybe in the future we want to have a special install
16191            // broadcast or such for apps, but we'd like to deliberately make
16192            // this decision.
16193            String skipPackages[] = null;
16194            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16195                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16196                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16197                Uri data = intent.getData();
16198                if (data != null) {
16199                    String pkgName = data.getSchemeSpecificPart();
16200                    if (pkgName != null) {
16201                        skipPackages = new String[] { pkgName };
16202                    }
16203                }
16204            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16205                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16206            }
16207            if (skipPackages != null && (skipPackages.length > 0)) {
16208                for (String skipPackage : skipPackages) {
16209                    if (skipPackage != null) {
16210                        int NT = receivers.size();
16211                        for (int it=0; it<NT; it++) {
16212                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16213                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16214                                receivers.remove(it);
16215                                it--;
16216                                NT--;
16217                            }
16218                        }
16219                    }
16220                }
16221            }
16222
16223            int NT = receivers != null ? receivers.size() : 0;
16224            int it = 0;
16225            ResolveInfo curt = null;
16226            BroadcastFilter curr = null;
16227            while (it < NT && ir < NR) {
16228                if (curt == null) {
16229                    curt = (ResolveInfo)receivers.get(it);
16230                }
16231                if (curr == null) {
16232                    curr = registeredReceivers.get(ir);
16233                }
16234                if (curr.getPriority() >= curt.priority) {
16235                    // Insert this broadcast record into the final list.
16236                    receivers.add(it, curr);
16237                    ir++;
16238                    curr = null;
16239                    it++;
16240                    NT++;
16241                } else {
16242                    // Skip to the next ResolveInfo in the final list.
16243                    it++;
16244                    curt = null;
16245                }
16246            }
16247        }
16248        while (ir < NR) {
16249            if (receivers == null) {
16250                receivers = new ArrayList();
16251            }
16252            receivers.add(registeredReceivers.get(ir));
16253            ir++;
16254        }
16255
16256        if ((receivers != null && receivers.size() > 0)
16257                || resultTo != null) {
16258            BroadcastQueue queue = broadcastQueueForIntent(intent);
16259            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16260                    callerPackage, callingPid, callingUid, resolvedType,
16261                    requiredPermission, appOp, receivers, resultTo, resultCode,
16262                    resultData, map, ordered, sticky, false, userId);
16263            if (DEBUG_BROADCAST) Slog.v(
16264                    TAG, "Enqueueing ordered broadcast " + r
16265                    + ": prev had " + queue.mOrderedBroadcasts.size());
16266            if (DEBUG_BROADCAST) {
16267                int seq = r.intent.getIntExtra("seq", -1);
16268                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16269            }
16270            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16271            if (!replaced) {
16272                queue.enqueueOrderedBroadcastLocked(r);
16273                queue.scheduleBroadcastsLocked();
16274            }
16275        }
16276
16277        return ActivityManager.BROADCAST_SUCCESS;
16278    }
16279
16280    final Intent verifyBroadcastLocked(Intent intent) {
16281        // Refuse possible leaked file descriptors
16282        if (intent != null && intent.hasFileDescriptors() == true) {
16283            throw new IllegalArgumentException("File descriptors passed in Intent");
16284        }
16285
16286        int flags = intent.getFlags();
16287
16288        if (!mProcessesReady) {
16289            // if the caller really truly claims to know what they're doing, go
16290            // ahead and allow the broadcast without launching any receivers
16291            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16292                intent = new Intent(intent);
16293                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16294            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16295                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16296                        + " before boot completion");
16297                throw new IllegalStateException("Cannot broadcast before boot completed");
16298            }
16299        }
16300
16301        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16302            throw new IllegalArgumentException(
16303                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16304        }
16305
16306        return intent;
16307    }
16308
16309    public final int broadcastIntent(IApplicationThread caller,
16310            Intent intent, String resolvedType, IIntentReceiver resultTo,
16311            int resultCode, String resultData, Bundle map,
16312            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16313        enforceNotIsolatedCaller("broadcastIntent");
16314        synchronized(this) {
16315            intent = verifyBroadcastLocked(intent);
16316
16317            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16318            final int callingPid = Binder.getCallingPid();
16319            final int callingUid = Binder.getCallingUid();
16320            final long origId = Binder.clearCallingIdentity();
16321            int res = broadcastIntentLocked(callerApp,
16322                    callerApp != null ? callerApp.info.packageName : null,
16323                    intent, resolvedType, resultTo,
16324                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16325                    callingPid, callingUid, userId);
16326            Binder.restoreCallingIdentity(origId);
16327            return res;
16328        }
16329    }
16330
16331    int broadcastIntentInPackage(String packageName, int uid,
16332            Intent intent, String resolvedType, IIntentReceiver resultTo,
16333            int resultCode, String resultData, Bundle map,
16334            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16335        synchronized(this) {
16336            intent = verifyBroadcastLocked(intent);
16337
16338            final long origId = Binder.clearCallingIdentity();
16339            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16340                    resultTo, resultCode, resultData, map, requiredPermission,
16341                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16342            Binder.restoreCallingIdentity(origId);
16343            return res;
16344        }
16345    }
16346
16347    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16348        // Refuse possible leaked file descriptors
16349        if (intent != null && intent.hasFileDescriptors() == true) {
16350            throw new IllegalArgumentException("File descriptors passed in Intent");
16351        }
16352
16353        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16354                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16355
16356        synchronized(this) {
16357            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16358                    != PackageManager.PERMISSION_GRANTED) {
16359                String msg = "Permission Denial: unbroadcastIntent() from pid="
16360                        + Binder.getCallingPid()
16361                        + ", uid=" + Binder.getCallingUid()
16362                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16363                Slog.w(TAG, msg);
16364                throw new SecurityException(msg);
16365            }
16366            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16367            if (stickies != null) {
16368                ArrayList<Intent> list = stickies.get(intent.getAction());
16369                if (list != null) {
16370                    int N = list.size();
16371                    int i;
16372                    for (i=0; i<N; i++) {
16373                        if (intent.filterEquals(list.get(i))) {
16374                            list.remove(i);
16375                            break;
16376                        }
16377                    }
16378                    if (list.size() <= 0) {
16379                        stickies.remove(intent.getAction());
16380                    }
16381                }
16382                if (stickies.size() <= 0) {
16383                    mStickyBroadcasts.remove(userId);
16384                }
16385            }
16386        }
16387    }
16388
16389    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16390            String resultData, Bundle resultExtras, boolean resultAbort) {
16391        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16392        if (r == null) {
16393            Slog.w(TAG, "finishReceiver called but not found on queue");
16394            return false;
16395        }
16396
16397        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16398    }
16399
16400    void backgroundServicesFinishedLocked(int userId) {
16401        for (BroadcastQueue queue : mBroadcastQueues) {
16402            queue.backgroundServicesFinishedLocked(userId);
16403        }
16404    }
16405
16406    public void finishReceiver(IBinder who, int resultCode, String resultData,
16407            Bundle resultExtras, boolean resultAbort) {
16408        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16409
16410        // Refuse possible leaked file descriptors
16411        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16412            throw new IllegalArgumentException("File descriptors passed in Bundle");
16413        }
16414
16415        final long origId = Binder.clearCallingIdentity();
16416        try {
16417            boolean doNext = false;
16418            BroadcastRecord r;
16419
16420            synchronized(this) {
16421                r = broadcastRecordForReceiverLocked(who);
16422                if (r != null) {
16423                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16424                        resultData, resultExtras, resultAbort, true);
16425                }
16426            }
16427
16428            if (doNext) {
16429                r.queue.processNextBroadcast(false);
16430            }
16431            trimApplications();
16432        } finally {
16433            Binder.restoreCallingIdentity(origId);
16434        }
16435    }
16436
16437    // =========================================================
16438    // INSTRUMENTATION
16439    // =========================================================
16440
16441    public boolean startInstrumentation(ComponentName className,
16442            String profileFile, int flags, Bundle arguments,
16443            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16444            int userId, String abiOverride) {
16445        enforceNotIsolatedCaller("startInstrumentation");
16446        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16447                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16448        // Refuse possible leaked file descriptors
16449        if (arguments != null && arguments.hasFileDescriptors()) {
16450            throw new IllegalArgumentException("File descriptors passed in Bundle");
16451        }
16452
16453        synchronized(this) {
16454            InstrumentationInfo ii = null;
16455            ApplicationInfo ai = null;
16456            try {
16457                ii = mContext.getPackageManager().getInstrumentationInfo(
16458                    className, STOCK_PM_FLAGS);
16459                ai = AppGlobals.getPackageManager().getApplicationInfo(
16460                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16461            } catch (PackageManager.NameNotFoundException e) {
16462            } catch (RemoteException e) {
16463            }
16464            if (ii == null) {
16465                reportStartInstrumentationFailure(watcher, className,
16466                        "Unable to find instrumentation info for: " + className);
16467                return false;
16468            }
16469            if (ai == null) {
16470                reportStartInstrumentationFailure(watcher, className,
16471                        "Unable to find instrumentation target package: " + ii.targetPackage);
16472                return false;
16473            }
16474
16475            int match = mContext.getPackageManager().checkSignatures(
16476                    ii.targetPackage, ii.packageName);
16477            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16478                String msg = "Permission Denial: starting instrumentation "
16479                        + className + " from pid="
16480                        + Binder.getCallingPid()
16481                        + ", uid=" + Binder.getCallingPid()
16482                        + " not allowed because package " + ii.packageName
16483                        + " does not have a signature matching the target "
16484                        + ii.targetPackage;
16485                reportStartInstrumentationFailure(watcher, className, msg);
16486                throw new SecurityException(msg);
16487            }
16488
16489            final long origId = Binder.clearCallingIdentity();
16490            // Instrumentation can kill and relaunch even persistent processes
16491            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16492                    "start instr");
16493            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16494            app.instrumentationClass = className;
16495            app.instrumentationInfo = ai;
16496            app.instrumentationProfileFile = profileFile;
16497            app.instrumentationArguments = arguments;
16498            app.instrumentationWatcher = watcher;
16499            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16500            app.instrumentationResultClass = className;
16501            Binder.restoreCallingIdentity(origId);
16502        }
16503
16504        return true;
16505    }
16506
16507    /**
16508     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16509     * error to the logs, but if somebody is watching, send the report there too.  This enables
16510     * the "am" command to report errors with more information.
16511     *
16512     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16513     * @param cn The component name of the instrumentation.
16514     * @param report The error report.
16515     */
16516    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16517            ComponentName cn, String report) {
16518        Slog.w(TAG, report);
16519        try {
16520            if (watcher != null) {
16521                Bundle results = new Bundle();
16522                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16523                results.putString("Error", report);
16524                watcher.instrumentationStatus(cn, -1, results);
16525            }
16526        } catch (RemoteException e) {
16527            Slog.w(TAG, e);
16528        }
16529    }
16530
16531    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16532        if (app.instrumentationWatcher != null) {
16533            try {
16534                // NOTE:  IInstrumentationWatcher *must* be oneway here
16535                app.instrumentationWatcher.instrumentationFinished(
16536                    app.instrumentationClass,
16537                    resultCode,
16538                    results);
16539            } catch (RemoteException e) {
16540            }
16541        }
16542        if (app.instrumentationUiAutomationConnection != null) {
16543            try {
16544                app.instrumentationUiAutomationConnection.shutdown();
16545            } catch (RemoteException re) {
16546                /* ignore */
16547            }
16548            // Only a UiAutomation can set this flag and now that
16549            // it is finished we make sure it is reset to its default.
16550            mUserIsMonkey = false;
16551        }
16552        app.instrumentationWatcher = null;
16553        app.instrumentationUiAutomationConnection = null;
16554        app.instrumentationClass = null;
16555        app.instrumentationInfo = null;
16556        app.instrumentationProfileFile = null;
16557        app.instrumentationArguments = null;
16558
16559        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16560                "finished inst");
16561    }
16562
16563    public void finishInstrumentation(IApplicationThread target,
16564            int resultCode, Bundle results) {
16565        int userId = UserHandle.getCallingUserId();
16566        // Refuse possible leaked file descriptors
16567        if (results != null && results.hasFileDescriptors()) {
16568            throw new IllegalArgumentException("File descriptors passed in Intent");
16569        }
16570
16571        synchronized(this) {
16572            ProcessRecord app = getRecordForAppLocked(target);
16573            if (app == null) {
16574                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16575                return;
16576            }
16577            final long origId = Binder.clearCallingIdentity();
16578            finishInstrumentationLocked(app, resultCode, results);
16579            Binder.restoreCallingIdentity(origId);
16580        }
16581    }
16582
16583    // =========================================================
16584    // CONFIGURATION
16585    // =========================================================
16586
16587    public ConfigurationInfo getDeviceConfigurationInfo() {
16588        ConfigurationInfo config = new ConfigurationInfo();
16589        synchronized (this) {
16590            config.reqTouchScreen = mConfiguration.touchscreen;
16591            config.reqKeyboardType = mConfiguration.keyboard;
16592            config.reqNavigation = mConfiguration.navigation;
16593            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16594                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16595                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16596            }
16597            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16598                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16599                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16600            }
16601            config.reqGlEsVersion = GL_ES_VERSION;
16602        }
16603        return config;
16604    }
16605
16606    ActivityStack getFocusedStack() {
16607        return mStackSupervisor.getFocusedStack();
16608    }
16609
16610    public Configuration getConfiguration() {
16611        Configuration ci;
16612        synchronized(this) {
16613            ci = new Configuration(mConfiguration);
16614        }
16615        return ci;
16616    }
16617
16618    public void updatePersistentConfiguration(Configuration values) {
16619        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16620                "updateConfiguration()");
16621        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16622                "updateConfiguration()");
16623        if (values == null) {
16624            throw new NullPointerException("Configuration must not be null");
16625        }
16626
16627        synchronized(this) {
16628            final long origId = Binder.clearCallingIdentity();
16629            updateConfigurationLocked(values, null, true, false);
16630            Binder.restoreCallingIdentity(origId);
16631        }
16632    }
16633
16634    public void updateConfiguration(Configuration values) {
16635        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16636                "updateConfiguration()");
16637
16638        synchronized(this) {
16639            if (values == null && mWindowManager != null) {
16640                // sentinel: fetch the current configuration from the window manager
16641                values = mWindowManager.computeNewConfiguration();
16642            }
16643
16644            if (mWindowManager != null) {
16645                mProcessList.applyDisplaySize(mWindowManager);
16646            }
16647
16648            final long origId = Binder.clearCallingIdentity();
16649            if (values != null) {
16650                Settings.System.clearConfiguration(values);
16651            }
16652            updateConfigurationLocked(values, null, false, false);
16653            Binder.restoreCallingIdentity(origId);
16654        }
16655    }
16656
16657    /**
16658     * Do either or both things: (1) change the current configuration, and (2)
16659     * make sure the given activity is running with the (now) current
16660     * configuration.  Returns true if the activity has been left running, or
16661     * false if <var>starting</var> is being destroyed to match the new
16662     * configuration.
16663     * @param persistent TODO
16664     */
16665    boolean updateConfigurationLocked(Configuration values,
16666            ActivityRecord starting, boolean persistent, boolean initLocale) {
16667        int changes = 0;
16668
16669        if (values != null) {
16670            Configuration newConfig = new Configuration(mConfiguration);
16671            changes = newConfig.updateFrom(values);
16672            if (changes != 0) {
16673                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16674                    Slog.i(TAG, "Updating configuration to: " + values);
16675                }
16676
16677                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16678
16679                if (values.locale != null && !initLocale) {
16680                    saveLocaleLocked(values.locale,
16681                                     !values.locale.equals(mConfiguration.locale),
16682                                     values.userSetLocale);
16683                }
16684
16685                mConfigurationSeq++;
16686                if (mConfigurationSeq <= 0) {
16687                    mConfigurationSeq = 1;
16688                }
16689                newConfig.seq = mConfigurationSeq;
16690                mConfiguration = newConfig;
16691                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16692                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16693                //mUsageStatsService.noteStartConfig(newConfig);
16694
16695                final Configuration configCopy = new Configuration(mConfiguration);
16696
16697                // TODO: If our config changes, should we auto dismiss any currently
16698                // showing dialogs?
16699                mShowDialogs = shouldShowDialogs(newConfig);
16700
16701                AttributeCache ac = AttributeCache.instance();
16702                if (ac != null) {
16703                    ac.updateConfiguration(configCopy);
16704                }
16705
16706                // Make sure all resources in our process are updated
16707                // right now, so that anyone who is going to retrieve
16708                // resource values after we return will be sure to get
16709                // the new ones.  This is especially important during
16710                // boot, where the first config change needs to guarantee
16711                // all resources have that config before following boot
16712                // code is executed.
16713                mSystemThread.applyConfigurationToResources(configCopy);
16714
16715                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16716                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16717                    msg.obj = new Configuration(configCopy);
16718                    mHandler.sendMessage(msg);
16719                }
16720
16721                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16722                    ProcessRecord app = mLruProcesses.get(i);
16723                    try {
16724                        if (app.thread != null) {
16725                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16726                                    + app.processName + " new config " + mConfiguration);
16727                            app.thread.scheduleConfigurationChanged(configCopy);
16728                        }
16729                    } catch (Exception e) {
16730                    }
16731                }
16732                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16733                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16734                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16735                        | Intent.FLAG_RECEIVER_FOREGROUND);
16736                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16737                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16738                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16739                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16740                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16741                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16742                    broadcastIntentLocked(null, null, intent,
16743                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16744                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16745                }
16746            }
16747        }
16748
16749        boolean kept = true;
16750        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16751        // mainStack is null during startup.
16752        if (mainStack != null) {
16753            if (changes != 0 && starting == null) {
16754                // If the configuration changed, and the caller is not already
16755                // in the process of starting an activity, then find the top
16756                // activity to check if its configuration needs to change.
16757                starting = mainStack.topRunningActivityLocked(null);
16758            }
16759
16760            if (starting != null) {
16761                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16762                // And we need to make sure at this point that all other activities
16763                // are made visible with the correct configuration.
16764                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16765            }
16766        }
16767
16768        if (values != null && mWindowManager != null) {
16769            mWindowManager.setNewConfiguration(mConfiguration);
16770        }
16771
16772        return kept;
16773    }
16774
16775    /**
16776     * Decide based on the configuration whether we should shouw the ANR,
16777     * crash, etc dialogs.  The idea is that if there is no affordnace to
16778     * press the on-screen buttons, we shouldn't show the dialog.
16779     *
16780     * A thought: SystemUI might also want to get told about this, the Power
16781     * dialog / global actions also might want different behaviors.
16782     */
16783    private static final boolean shouldShowDialogs(Configuration config) {
16784        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16785                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16786    }
16787
16788    /**
16789     * Save the locale.  You must be inside a synchronized (this) block.
16790     */
16791    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16792        if(isDiff) {
16793            SystemProperties.set("user.language", l.getLanguage());
16794            SystemProperties.set("user.region", l.getCountry());
16795        }
16796
16797        if(isPersist) {
16798            SystemProperties.set("persist.sys.language", l.getLanguage());
16799            SystemProperties.set("persist.sys.country", l.getCountry());
16800            SystemProperties.set("persist.sys.localevar", l.getVariant());
16801
16802            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16803        }
16804    }
16805
16806    @Override
16807    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16808        synchronized (this) {
16809            ActivityRecord srec = ActivityRecord.forToken(token);
16810            if (srec.task != null && srec.task.stack != null) {
16811                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16812            }
16813        }
16814        return false;
16815    }
16816
16817    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16818            Intent resultData) {
16819
16820        synchronized (this) {
16821            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16822            if (stack != null) {
16823                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16824            }
16825            return false;
16826        }
16827    }
16828
16829    public int getLaunchedFromUid(IBinder activityToken) {
16830        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16831        if (srec == null) {
16832            return -1;
16833        }
16834        return srec.launchedFromUid;
16835    }
16836
16837    public String getLaunchedFromPackage(IBinder activityToken) {
16838        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16839        if (srec == null) {
16840            return null;
16841        }
16842        return srec.launchedFromPackage;
16843    }
16844
16845    // =========================================================
16846    // LIFETIME MANAGEMENT
16847    // =========================================================
16848
16849    // Returns which broadcast queue the app is the current [or imminent] receiver
16850    // on, or 'null' if the app is not an active broadcast recipient.
16851    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16852        BroadcastRecord r = app.curReceiver;
16853        if (r != null) {
16854            return r.queue;
16855        }
16856
16857        // It's not the current receiver, but it might be starting up to become one
16858        synchronized (this) {
16859            for (BroadcastQueue queue : mBroadcastQueues) {
16860                r = queue.mPendingBroadcast;
16861                if (r != null && r.curApp == app) {
16862                    // found it; report which queue it's in
16863                    return queue;
16864                }
16865            }
16866        }
16867
16868        return null;
16869    }
16870
16871    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16872            ComponentName targetComponent, String targetProcess) {
16873        if (!mTrackingAssociations) {
16874            return null;
16875        }
16876        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16877                = mAssociations.get(targetUid);
16878        if (components == null) {
16879            components = new ArrayMap<>();
16880            mAssociations.put(targetUid, components);
16881        }
16882        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16883        if (sourceUids == null) {
16884            sourceUids = new SparseArray<>();
16885            components.put(targetComponent, sourceUids);
16886        }
16887        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16888        if (sourceProcesses == null) {
16889            sourceProcesses = new ArrayMap<>();
16890            sourceUids.put(sourceUid, sourceProcesses);
16891        }
16892        Association ass = sourceProcesses.get(sourceProcess);
16893        if (ass == null) {
16894            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16895                    targetProcess);
16896            sourceProcesses.put(sourceProcess, ass);
16897        }
16898        ass.mCount++;
16899        ass.mNesting++;
16900        if (ass.mNesting == 1) {
16901            ass.mStartTime = SystemClock.uptimeMillis();
16902        }
16903        return ass;
16904    }
16905
16906    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16907            ComponentName targetComponent) {
16908        if (!mTrackingAssociations) {
16909            return;
16910        }
16911        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16912                = mAssociations.get(targetUid);
16913        if (components == null) {
16914            return;
16915        }
16916        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16917        if (sourceUids == null) {
16918            return;
16919        }
16920        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16921        if (sourceProcesses == null) {
16922            return;
16923        }
16924        Association ass = sourceProcesses.get(sourceProcess);
16925        if (ass == null || ass.mNesting <= 0) {
16926            return;
16927        }
16928        ass.mNesting--;
16929        if (ass.mNesting == 0) {
16930            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16931        }
16932    }
16933
16934    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16935            boolean doingAll, long now) {
16936        if (mAdjSeq == app.adjSeq) {
16937            // This adjustment has already been computed.
16938            return app.curRawAdj;
16939        }
16940
16941        if (app.thread == null) {
16942            app.adjSeq = mAdjSeq;
16943            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16944            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16945            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16946        }
16947
16948        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16949        app.adjSource = null;
16950        app.adjTarget = null;
16951        app.empty = false;
16952        app.cached = false;
16953
16954        final int activitiesSize = app.activities.size();
16955
16956        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16957            // The max adjustment doesn't allow this app to be anything
16958            // below foreground, so it is not worth doing work for it.
16959            app.adjType = "fixed";
16960            app.adjSeq = mAdjSeq;
16961            app.curRawAdj = app.maxAdj;
16962            app.foregroundActivities = false;
16963            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16964            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16965            // System processes can do UI, and when they do we want to have
16966            // them trim their memory after the user leaves the UI.  To
16967            // facilitate this, here we need to determine whether or not it
16968            // is currently showing UI.
16969            app.systemNoUi = true;
16970            if (app == TOP_APP) {
16971                app.systemNoUi = false;
16972            } else if (activitiesSize > 0) {
16973                for (int j = 0; j < activitiesSize; j++) {
16974                    final ActivityRecord r = app.activities.get(j);
16975                    if (r.visible) {
16976                        app.systemNoUi = false;
16977                    }
16978                }
16979            }
16980            if (!app.systemNoUi) {
16981                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16982            }
16983            return (app.curAdj=app.maxAdj);
16984        }
16985
16986        app.systemNoUi = false;
16987
16988        // Determine the importance of the process, starting with most
16989        // important to least, and assign an appropriate OOM adjustment.
16990        int adj;
16991        int schedGroup;
16992        int procState;
16993        boolean foregroundActivities = false;
16994        BroadcastQueue queue;
16995        if (app == TOP_APP) {
16996            // The last app on the list is the foreground app.
16997            adj = ProcessList.FOREGROUND_APP_ADJ;
16998            schedGroup = Process.THREAD_GROUP_DEFAULT;
16999            app.adjType = "top-activity";
17000            foregroundActivities = true;
17001            procState = ActivityManager.PROCESS_STATE_TOP;
17002        } else if (app.instrumentationClass != null) {
17003            // Don't want to kill running instrumentation.
17004            adj = ProcessList.FOREGROUND_APP_ADJ;
17005            schedGroup = Process.THREAD_GROUP_DEFAULT;
17006            app.adjType = "instrumentation";
17007            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17008        } else if ((queue = isReceivingBroadcast(app)) != null) {
17009            // An app that is currently receiving a broadcast also
17010            // counts as being in the foreground for OOM killer purposes.
17011            // It's placed in a sched group based on the nature of the
17012            // broadcast as reflected by which queue it's active in.
17013            adj = ProcessList.FOREGROUND_APP_ADJ;
17014            schedGroup = (queue == mFgBroadcastQueue)
17015                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17016            app.adjType = "broadcast";
17017            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17018        } else if (app.executingServices.size() > 0) {
17019            // An app that is currently executing a service callback also
17020            // counts as being in the foreground.
17021            adj = ProcessList.FOREGROUND_APP_ADJ;
17022            schedGroup = app.execServicesFg ?
17023                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17024            app.adjType = "exec-service";
17025            procState = ActivityManager.PROCESS_STATE_SERVICE;
17026            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17027        } else {
17028            // As far as we know the process is empty.  We may change our mind later.
17029            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17030            // At this point we don't actually know the adjustment.  Use the cached adj
17031            // value that the caller wants us to.
17032            adj = cachedAdj;
17033            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17034            app.cached = true;
17035            app.empty = true;
17036            app.adjType = "cch-empty";
17037        }
17038
17039        // Examine all activities if not already foreground.
17040        if (!foregroundActivities && activitiesSize > 0) {
17041            for (int j = 0; j < activitiesSize; j++) {
17042                final ActivityRecord r = app.activities.get(j);
17043                if (r.app != app) {
17044                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17045                            + app + "?!?");
17046                    continue;
17047                }
17048                if (r.visible) {
17049                    // App has a visible activity; only upgrade adjustment.
17050                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17051                        adj = ProcessList.VISIBLE_APP_ADJ;
17052                        app.adjType = "visible";
17053                    }
17054                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17055                        procState = ActivityManager.PROCESS_STATE_TOP;
17056                    }
17057                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17058                    app.cached = false;
17059                    app.empty = false;
17060                    foregroundActivities = true;
17061                    break;
17062                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17063                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17064                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17065                        app.adjType = "pausing";
17066                    }
17067                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17068                        procState = ActivityManager.PROCESS_STATE_TOP;
17069                    }
17070                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17071                    app.cached = false;
17072                    app.empty = false;
17073                    foregroundActivities = true;
17074                } else if (r.state == ActivityState.STOPPING) {
17075                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17076                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17077                        app.adjType = "stopping";
17078                    }
17079                    // For the process state, we will at this point consider the
17080                    // process to be cached.  It will be cached either as an activity
17081                    // or empty depending on whether the activity is finishing.  We do
17082                    // this so that we can treat the process as cached for purposes of
17083                    // memory trimming (determing current memory level, trim command to
17084                    // send to process) since there can be an arbitrary number of stopping
17085                    // processes and they should soon all go into the cached state.
17086                    if (!r.finishing) {
17087                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17088                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17089                        }
17090                    }
17091                    app.cached = false;
17092                    app.empty = false;
17093                    foregroundActivities = true;
17094                } else {
17095                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17096                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17097                        app.adjType = "cch-act";
17098                    }
17099                }
17100            }
17101        }
17102
17103        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17104            if (app.foregroundServices) {
17105                // The user is aware of this app, so make it visible.
17106                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17107                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17108                app.cached = false;
17109                app.adjType = "fg-service";
17110                schedGroup = Process.THREAD_GROUP_DEFAULT;
17111            } else if (app.forcingToForeground != null) {
17112                // The user is aware of this app, so make it visible.
17113                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17114                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17115                app.cached = false;
17116                app.adjType = "force-fg";
17117                app.adjSource = app.forcingToForeground;
17118                schedGroup = Process.THREAD_GROUP_DEFAULT;
17119            }
17120        }
17121
17122        if (app == mHeavyWeightProcess) {
17123            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17124                // We don't want to kill the current heavy-weight process.
17125                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17126                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17127                app.cached = false;
17128                app.adjType = "heavy";
17129            }
17130            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17131                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17132            }
17133        }
17134
17135        if (app == mHomeProcess) {
17136            if (adj > ProcessList.HOME_APP_ADJ) {
17137                // This process is hosting what we currently consider to be the
17138                // home app, so we don't want to let it go into the background.
17139                adj = ProcessList.HOME_APP_ADJ;
17140                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17141                app.cached = false;
17142                app.adjType = "home";
17143            }
17144            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17145                procState = ActivityManager.PROCESS_STATE_HOME;
17146            }
17147        }
17148
17149        if (app == mPreviousProcess && app.activities.size() > 0) {
17150            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17151                // This was the previous process that showed UI to the user.
17152                // We want to try to keep it around more aggressively, to give
17153                // a good experience around switching between two apps.
17154                adj = ProcessList.PREVIOUS_APP_ADJ;
17155                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17156                app.cached = false;
17157                app.adjType = "previous";
17158            }
17159            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17160                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17161            }
17162        }
17163
17164        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17165                + " reason=" + app.adjType);
17166
17167        // By default, we use the computed adjustment.  It may be changed if
17168        // there are applications dependent on our services or providers, but
17169        // this gives us a baseline and makes sure we don't get into an
17170        // infinite recursion.
17171        app.adjSeq = mAdjSeq;
17172        app.curRawAdj = adj;
17173        app.hasStartedServices = false;
17174
17175        if (mBackupTarget != null && app == mBackupTarget.app) {
17176            // If possible we want to avoid killing apps while they're being backed up
17177            if (adj > ProcessList.BACKUP_APP_ADJ) {
17178                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17179                adj = ProcessList.BACKUP_APP_ADJ;
17180                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17181                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17182                }
17183                app.adjType = "backup";
17184                app.cached = false;
17185            }
17186            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17187                procState = ActivityManager.PROCESS_STATE_BACKUP;
17188            }
17189        }
17190
17191        boolean mayBeTop = false;
17192
17193        for (int is = app.services.size()-1;
17194                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17195                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17196                        || procState > ActivityManager.PROCESS_STATE_TOP);
17197                is--) {
17198            ServiceRecord s = app.services.valueAt(is);
17199            if (s.startRequested) {
17200                app.hasStartedServices = true;
17201                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17202                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17203                }
17204                if (app.hasShownUi && app != mHomeProcess) {
17205                    // If this process has shown some UI, let it immediately
17206                    // go to the LRU list because it may be pretty heavy with
17207                    // UI stuff.  We'll tag it with a label just to help
17208                    // debug and understand what is going on.
17209                    if (adj > ProcessList.SERVICE_ADJ) {
17210                        app.adjType = "cch-started-ui-services";
17211                    }
17212                } else {
17213                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17214                        // This service has seen some activity within
17215                        // recent memory, so we will keep its process ahead
17216                        // of the background processes.
17217                        if (adj > ProcessList.SERVICE_ADJ) {
17218                            adj = ProcessList.SERVICE_ADJ;
17219                            app.adjType = "started-services";
17220                            app.cached = false;
17221                        }
17222                    }
17223                    // If we have let the service slide into the background
17224                    // state, still have some text describing what it is doing
17225                    // even though the service no longer has an impact.
17226                    if (adj > ProcessList.SERVICE_ADJ) {
17227                        app.adjType = "cch-started-services";
17228                    }
17229                }
17230            }
17231            for (int conni = s.connections.size()-1;
17232                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17233                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17234                            || procState > ActivityManager.PROCESS_STATE_TOP);
17235                    conni--) {
17236                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17237                for (int i = 0;
17238                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17239                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17240                                || procState > ActivityManager.PROCESS_STATE_TOP);
17241                        i++) {
17242                    // XXX should compute this based on the max of
17243                    // all connected clients.
17244                    ConnectionRecord cr = clist.get(i);
17245                    if (cr.binding.client == app) {
17246                        // Binding to ourself is not interesting.
17247                        continue;
17248                    }
17249                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17250                        ProcessRecord client = cr.binding.client;
17251                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17252                                TOP_APP, doingAll, now);
17253                        int clientProcState = client.curProcState;
17254                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17255                            // If the other app is cached for any reason, for purposes here
17256                            // we are going to consider it empty.  The specific cached state
17257                            // doesn't propagate except under certain conditions.
17258                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17259                        }
17260                        String adjType = null;
17261                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17262                            // Not doing bind OOM management, so treat
17263                            // this guy more like a started service.
17264                            if (app.hasShownUi && app != mHomeProcess) {
17265                                // If this process has shown some UI, let it immediately
17266                                // go to the LRU list because it may be pretty heavy with
17267                                // UI stuff.  We'll tag it with a label just to help
17268                                // debug and understand what is going on.
17269                                if (adj > clientAdj) {
17270                                    adjType = "cch-bound-ui-services";
17271                                }
17272                                app.cached = false;
17273                                clientAdj = adj;
17274                                clientProcState = procState;
17275                            } else {
17276                                if (now >= (s.lastActivity
17277                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17278                                    // This service has not seen activity within
17279                                    // recent memory, so allow it to drop to the
17280                                    // LRU list if there is no other reason to keep
17281                                    // it around.  We'll also tag it with a label just
17282                                    // to help debug and undertand what is going on.
17283                                    if (adj > clientAdj) {
17284                                        adjType = "cch-bound-services";
17285                                    }
17286                                    clientAdj = adj;
17287                                }
17288                            }
17289                        }
17290                        if (adj > clientAdj) {
17291                            // If this process has recently shown UI, and
17292                            // the process that is binding to it is less
17293                            // important than being visible, then we don't
17294                            // care about the binding as much as we care
17295                            // about letting this process get into the LRU
17296                            // list to be killed and restarted if needed for
17297                            // memory.
17298                            if (app.hasShownUi && app != mHomeProcess
17299                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17300                                adjType = "cch-bound-ui-services";
17301                            } else {
17302                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17303                                        |Context.BIND_IMPORTANT)) != 0) {
17304                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17305                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17306                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17307                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17308                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17309                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17310                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17311                                    adj = clientAdj;
17312                                } else {
17313                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17314                                        adj = ProcessList.VISIBLE_APP_ADJ;
17315                                    }
17316                                }
17317                                if (!client.cached) {
17318                                    app.cached = false;
17319                                }
17320                                adjType = "service";
17321                            }
17322                        }
17323                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17324                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17325                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17326                            }
17327                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17328                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17329                                    // Special handling of clients who are in the top state.
17330                                    // We *may* want to consider this process to be in the
17331                                    // top state as well, but only if there is not another
17332                                    // reason for it to be running.  Being on the top is a
17333                                    // special state, meaning you are specifically running
17334                                    // for the current top app.  If the process is already
17335                                    // running in the background for some other reason, it
17336                                    // is more important to continue considering it to be
17337                                    // in the background state.
17338                                    mayBeTop = true;
17339                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17340                                } else {
17341                                    // Special handling for above-top states (persistent
17342                                    // processes).  These should not bring the current process
17343                                    // into the top state, since they are not on top.  Instead
17344                                    // give them the best state after that.
17345                                    clientProcState =
17346                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17347                                }
17348                            }
17349                        } else {
17350                            if (clientProcState <
17351                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17352                                clientProcState =
17353                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17354                            }
17355                        }
17356                        if (procState > clientProcState) {
17357                            procState = clientProcState;
17358                        }
17359                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17360                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17361                            app.pendingUiClean = true;
17362                        }
17363                        if (adjType != null) {
17364                            app.adjType = adjType;
17365                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17366                                    .REASON_SERVICE_IN_USE;
17367                            app.adjSource = cr.binding.client;
17368                            app.adjSourceProcState = clientProcState;
17369                            app.adjTarget = s.name;
17370                        }
17371                    }
17372                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17373                        app.treatLikeActivity = true;
17374                    }
17375                    final ActivityRecord a = cr.activity;
17376                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17377                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17378                                (a.visible || a.state == ActivityState.RESUMED
17379                                 || a.state == ActivityState.PAUSING)) {
17380                            adj = ProcessList.FOREGROUND_APP_ADJ;
17381                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17382                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17383                            }
17384                            app.cached = false;
17385                            app.adjType = "service";
17386                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17387                                    .REASON_SERVICE_IN_USE;
17388                            app.adjSource = a;
17389                            app.adjSourceProcState = procState;
17390                            app.adjTarget = s.name;
17391                        }
17392                    }
17393                }
17394            }
17395        }
17396
17397        for (int provi = app.pubProviders.size()-1;
17398                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17399                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17400                        || procState > ActivityManager.PROCESS_STATE_TOP);
17401                provi--) {
17402            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17403            for (int i = cpr.connections.size()-1;
17404                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17405                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17406                            || procState > ActivityManager.PROCESS_STATE_TOP);
17407                    i--) {
17408                ContentProviderConnection conn = cpr.connections.get(i);
17409                ProcessRecord client = conn.client;
17410                if (client == app) {
17411                    // Being our own client is not interesting.
17412                    continue;
17413                }
17414                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17415                int clientProcState = client.curProcState;
17416                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17417                    // If the other app is cached for any reason, for purposes here
17418                    // we are going to consider it empty.
17419                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17420                }
17421                if (adj > clientAdj) {
17422                    if (app.hasShownUi && app != mHomeProcess
17423                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17424                        app.adjType = "cch-ui-provider";
17425                    } else {
17426                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17427                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17428                        app.adjType = "provider";
17429                    }
17430                    app.cached &= client.cached;
17431                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17432                            .REASON_PROVIDER_IN_USE;
17433                    app.adjSource = client;
17434                    app.adjSourceProcState = clientProcState;
17435                    app.adjTarget = cpr.name;
17436                }
17437                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17438                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17439                        // Special handling of clients who are in the top state.
17440                        // We *may* want to consider this process to be in the
17441                        // top state as well, but only if there is not another
17442                        // reason for it to be running.  Being on the top is a
17443                        // special state, meaning you are specifically running
17444                        // for the current top app.  If the process is already
17445                        // running in the background for some other reason, it
17446                        // is more important to continue considering it to be
17447                        // in the background state.
17448                        mayBeTop = true;
17449                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17450                    } else {
17451                        // Special handling for above-top states (persistent
17452                        // processes).  These should not bring the current process
17453                        // into the top state, since they are not on top.  Instead
17454                        // give them the best state after that.
17455                        clientProcState =
17456                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17457                    }
17458                }
17459                if (procState > clientProcState) {
17460                    procState = clientProcState;
17461                }
17462                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17463                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17464                }
17465            }
17466            // If the provider has external (non-framework) process
17467            // dependencies, ensure that its adjustment is at least
17468            // FOREGROUND_APP_ADJ.
17469            if (cpr.hasExternalProcessHandles()) {
17470                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17471                    adj = ProcessList.FOREGROUND_APP_ADJ;
17472                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17473                    app.cached = false;
17474                    app.adjType = "provider";
17475                    app.adjTarget = cpr.name;
17476                }
17477                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17478                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17479                }
17480            }
17481        }
17482
17483        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17484            // A client of one of our services or providers is in the top state.  We
17485            // *may* want to be in the top state, but not if we are already running in
17486            // the background for some other reason.  For the decision here, we are going
17487            // to pick out a few specific states that we want to remain in when a client
17488            // is top (states that tend to be longer-term) and otherwise allow it to go
17489            // to the top state.
17490            switch (procState) {
17491                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17492                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17493                case ActivityManager.PROCESS_STATE_SERVICE:
17494                    // These all are longer-term states, so pull them up to the top
17495                    // of the background states, but not all the way to the top state.
17496                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17497                    break;
17498                default:
17499                    // Otherwise, top is a better choice, so take it.
17500                    procState = ActivityManager.PROCESS_STATE_TOP;
17501                    break;
17502            }
17503        }
17504
17505        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17506            if (app.hasClientActivities) {
17507                // This is a cached process, but with client activities.  Mark it so.
17508                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17509                app.adjType = "cch-client-act";
17510            } else if (app.treatLikeActivity) {
17511                // This is a cached process, but somebody wants us to treat it like it has
17512                // an activity, okay!
17513                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17514                app.adjType = "cch-as-act";
17515            }
17516        }
17517
17518        if (adj == ProcessList.SERVICE_ADJ) {
17519            if (doingAll) {
17520                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17521                mNewNumServiceProcs++;
17522                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17523                if (!app.serviceb) {
17524                    // This service isn't far enough down on the LRU list to
17525                    // normally be a B service, but if we are low on RAM and it
17526                    // is large we want to force it down since we would prefer to
17527                    // keep launcher over it.
17528                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17529                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17530                        app.serviceHighRam = true;
17531                        app.serviceb = true;
17532                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17533                    } else {
17534                        mNewNumAServiceProcs++;
17535                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17536                    }
17537                } else {
17538                    app.serviceHighRam = false;
17539                }
17540            }
17541            if (app.serviceb) {
17542                adj = ProcessList.SERVICE_B_ADJ;
17543            }
17544        }
17545
17546        app.curRawAdj = adj;
17547
17548        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17549        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17550        if (adj > app.maxAdj) {
17551            adj = app.maxAdj;
17552            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17553                schedGroup = Process.THREAD_GROUP_DEFAULT;
17554            }
17555        }
17556
17557        // Do final modification to adj.  Everything we do between here and applying
17558        // the final setAdj must be done in this function, because we will also use
17559        // it when computing the final cached adj later.  Note that we don't need to
17560        // worry about this for max adj above, since max adj will always be used to
17561        // keep it out of the cached vaues.
17562        app.curAdj = app.modifyRawOomAdj(adj);
17563        app.curSchedGroup = schedGroup;
17564        app.curProcState = procState;
17565        app.foregroundActivities = foregroundActivities;
17566
17567        return app.curRawAdj;
17568    }
17569
17570    /**
17571     * Record new PSS sample for a process.
17572     */
17573    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17574        proc.lastPssTime = now;
17575        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17576        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17577                + ": " + pss + " lastPss=" + proc.lastPss
17578                + " state=" + ProcessList.makeProcStateString(procState));
17579        if (proc.initialIdlePss == 0) {
17580            proc.initialIdlePss = pss;
17581        }
17582        proc.lastPss = pss;
17583        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17584            proc.lastCachedPss = pss;
17585        }
17586    }
17587
17588    /**
17589     * Schedule PSS collection of a process.
17590     */
17591    void requestPssLocked(ProcessRecord proc, int procState) {
17592        if (mPendingPssProcesses.contains(proc)) {
17593            return;
17594        }
17595        if (mPendingPssProcesses.size() == 0) {
17596            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17597        }
17598        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17599        proc.pssProcState = procState;
17600        mPendingPssProcesses.add(proc);
17601    }
17602
17603    /**
17604     * Schedule PSS collection of all processes.
17605     */
17606    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17607        if (!always) {
17608            if (now < (mLastFullPssTime +
17609                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17610                return;
17611            }
17612        }
17613        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17614        mLastFullPssTime = now;
17615        mFullPssPending = true;
17616        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17617        mPendingPssProcesses.clear();
17618        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17619            ProcessRecord app = mLruProcesses.get(i);
17620            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17621                app.pssProcState = app.setProcState;
17622                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17623                        mTestPssMode, isSleeping(), now);
17624                mPendingPssProcesses.add(app);
17625            }
17626        }
17627        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17628    }
17629
17630    public void setTestPssMode(boolean enabled) {
17631        synchronized (this) {
17632            mTestPssMode = enabled;
17633            if (enabled) {
17634                // Whenever we enable the mode, we want to take a snapshot all of current
17635                // process mem use.
17636                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17637            }
17638        }
17639    }
17640
17641    /**
17642     * Ask a given process to GC right now.
17643     */
17644    final void performAppGcLocked(ProcessRecord app) {
17645        try {
17646            app.lastRequestedGc = SystemClock.uptimeMillis();
17647            if (app.thread != null) {
17648                if (app.reportLowMemory) {
17649                    app.reportLowMemory = false;
17650                    app.thread.scheduleLowMemory();
17651                } else {
17652                    app.thread.processInBackground();
17653                }
17654            }
17655        } catch (Exception e) {
17656            // whatever.
17657        }
17658    }
17659
17660    /**
17661     * Returns true if things are idle enough to perform GCs.
17662     */
17663    private final boolean canGcNowLocked() {
17664        boolean processingBroadcasts = false;
17665        for (BroadcastQueue q : mBroadcastQueues) {
17666            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17667                processingBroadcasts = true;
17668            }
17669        }
17670        return !processingBroadcasts
17671                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17672    }
17673
17674    /**
17675     * Perform GCs on all processes that are waiting for it, but only
17676     * if things are idle.
17677     */
17678    final void performAppGcsLocked() {
17679        final int N = mProcessesToGc.size();
17680        if (N <= 0) {
17681            return;
17682        }
17683        if (canGcNowLocked()) {
17684            while (mProcessesToGc.size() > 0) {
17685                ProcessRecord proc = mProcessesToGc.remove(0);
17686                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17687                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17688                            <= SystemClock.uptimeMillis()) {
17689                        // To avoid spamming the system, we will GC processes one
17690                        // at a time, waiting a few seconds between each.
17691                        performAppGcLocked(proc);
17692                        scheduleAppGcsLocked();
17693                        return;
17694                    } else {
17695                        // It hasn't been long enough since we last GCed this
17696                        // process...  put it in the list to wait for its time.
17697                        addProcessToGcListLocked(proc);
17698                        break;
17699                    }
17700                }
17701            }
17702
17703            scheduleAppGcsLocked();
17704        }
17705    }
17706
17707    /**
17708     * If all looks good, perform GCs on all processes waiting for them.
17709     */
17710    final void performAppGcsIfAppropriateLocked() {
17711        if (canGcNowLocked()) {
17712            performAppGcsLocked();
17713            return;
17714        }
17715        // Still not idle, wait some more.
17716        scheduleAppGcsLocked();
17717    }
17718
17719    /**
17720     * Schedule the execution of all pending app GCs.
17721     */
17722    final void scheduleAppGcsLocked() {
17723        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17724
17725        if (mProcessesToGc.size() > 0) {
17726            // Schedule a GC for the time to the next process.
17727            ProcessRecord proc = mProcessesToGc.get(0);
17728            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17729
17730            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17731            long now = SystemClock.uptimeMillis();
17732            if (when < (now+GC_TIMEOUT)) {
17733                when = now + GC_TIMEOUT;
17734            }
17735            mHandler.sendMessageAtTime(msg, when);
17736        }
17737    }
17738
17739    /**
17740     * Add a process to the array of processes waiting to be GCed.  Keeps the
17741     * list in sorted order by the last GC time.  The process can't already be
17742     * on the list.
17743     */
17744    final void addProcessToGcListLocked(ProcessRecord proc) {
17745        boolean added = false;
17746        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17747            if (mProcessesToGc.get(i).lastRequestedGc <
17748                    proc.lastRequestedGc) {
17749                added = true;
17750                mProcessesToGc.add(i+1, proc);
17751                break;
17752            }
17753        }
17754        if (!added) {
17755            mProcessesToGc.add(0, proc);
17756        }
17757    }
17758
17759    /**
17760     * Set up to ask a process to GC itself.  This will either do it
17761     * immediately, or put it on the list of processes to gc the next
17762     * time things are idle.
17763     */
17764    final void scheduleAppGcLocked(ProcessRecord app) {
17765        long now = SystemClock.uptimeMillis();
17766        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17767            return;
17768        }
17769        if (!mProcessesToGc.contains(app)) {
17770            addProcessToGcListLocked(app);
17771            scheduleAppGcsLocked();
17772        }
17773    }
17774
17775    final void checkExcessivePowerUsageLocked(boolean doKills) {
17776        updateCpuStatsNow();
17777
17778        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17779        boolean doWakeKills = doKills;
17780        boolean doCpuKills = doKills;
17781        if (mLastPowerCheckRealtime == 0) {
17782            doWakeKills = false;
17783        }
17784        if (mLastPowerCheckUptime == 0) {
17785            doCpuKills = false;
17786        }
17787        if (stats.isScreenOn()) {
17788            doWakeKills = false;
17789        }
17790        final long curRealtime = SystemClock.elapsedRealtime();
17791        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17792        final long curUptime = SystemClock.uptimeMillis();
17793        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17794        mLastPowerCheckRealtime = curRealtime;
17795        mLastPowerCheckUptime = curUptime;
17796        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17797            doWakeKills = false;
17798        }
17799        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17800            doCpuKills = false;
17801        }
17802        int i = mLruProcesses.size();
17803        while (i > 0) {
17804            i--;
17805            ProcessRecord app = mLruProcesses.get(i);
17806            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17807                long wtime;
17808                synchronized (stats) {
17809                    wtime = stats.getProcessWakeTime(app.info.uid,
17810                            app.pid, curRealtime);
17811                }
17812                long wtimeUsed = wtime - app.lastWakeTime;
17813                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17814                if (DEBUG_POWER) {
17815                    StringBuilder sb = new StringBuilder(128);
17816                    sb.append("Wake for ");
17817                    app.toShortString(sb);
17818                    sb.append(": over ");
17819                    TimeUtils.formatDuration(realtimeSince, sb);
17820                    sb.append(" used ");
17821                    TimeUtils.formatDuration(wtimeUsed, sb);
17822                    sb.append(" (");
17823                    sb.append((wtimeUsed*100)/realtimeSince);
17824                    sb.append("%)");
17825                    Slog.i(TAG, sb.toString());
17826                    sb.setLength(0);
17827                    sb.append("CPU for ");
17828                    app.toShortString(sb);
17829                    sb.append(": over ");
17830                    TimeUtils.formatDuration(uptimeSince, sb);
17831                    sb.append(" used ");
17832                    TimeUtils.formatDuration(cputimeUsed, sb);
17833                    sb.append(" (");
17834                    sb.append((cputimeUsed*100)/uptimeSince);
17835                    sb.append("%)");
17836                    Slog.i(TAG, sb.toString());
17837                }
17838                // If a process has held a wake lock for more
17839                // than 50% of the time during this period,
17840                // that sounds bad.  Kill!
17841                if (doWakeKills && realtimeSince > 0
17842                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17843                    synchronized (stats) {
17844                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17845                                realtimeSince, wtimeUsed);
17846                    }
17847                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17848                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17849                } else if (doCpuKills && uptimeSince > 0
17850                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17851                    synchronized (stats) {
17852                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17853                                uptimeSince, cputimeUsed);
17854                    }
17855                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17856                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17857                } else {
17858                    app.lastWakeTime = wtime;
17859                    app.lastCpuTime = app.curCpuTime;
17860                }
17861            }
17862        }
17863    }
17864
17865    private final boolean applyOomAdjLocked(ProcessRecord app,
17866            ProcessRecord TOP_APP, boolean doingAll, long now) {
17867        boolean success = true;
17868
17869        if (app.curRawAdj != app.setRawAdj) {
17870            app.setRawAdj = app.curRawAdj;
17871        }
17872
17873        int changes = 0;
17874
17875        if (app.curAdj != app.setAdj) {
17876            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17877            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17878                TAG, "Set " + app.pid + " " + app.processName +
17879                " adj " + app.curAdj + ": " + app.adjType);
17880            app.setAdj = app.curAdj;
17881        }
17882
17883        if (app.setSchedGroup != app.curSchedGroup) {
17884            app.setSchedGroup = app.curSchedGroup;
17885            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17886                    "Setting process group of " + app.processName
17887                    + " to " + app.curSchedGroup);
17888            if (app.waitingToKill != null &&
17889                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17890                app.kill(app.waitingToKill, true);
17891                success = false;
17892            } else {
17893                if (true) {
17894                    long oldId = Binder.clearCallingIdentity();
17895                    try {
17896                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17897                    } catch (Exception e) {
17898                        Slog.w(TAG, "Failed setting process group of " + app.pid
17899                                + " to " + app.curSchedGroup);
17900                        e.printStackTrace();
17901                    } finally {
17902                        Binder.restoreCallingIdentity(oldId);
17903                    }
17904                } else {
17905                    if (app.thread != null) {
17906                        try {
17907                            app.thread.setSchedulingGroup(app.curSchedGroup);
17908                        } catch (RemoteException e) {
17909                        }
17910                    }
17911                }
17912                Process.setSwappiness(app.pid,
17913                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17914            }
17915        }
17916        if (app.repForegroundActivities != app.foregroundActivities) {
17917            app.repForegroundActivities = app.foregroundActivities;
17918            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17919        }
17920        if (app.repProcState != app.curProcState) {
17921            app.repProcState = app.curProcState;
17922            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17923            if (app.thread != null) {
17924                try {
17925                    if (false) {
17926                        //RuntimeException h = new RuntimeException("here");
17927                        Slog.i(TAG, "Sending new process state " + app.repProcState
17928                                + " to " + app /*, h*/);
17929                    }
17930                    app.thread.setProcessState(app.repProcState);
17931                } catch (RemoteException e) {
17932                }
17933            }
17934        }
17935        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17936                app.setProcState)) {
17937            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17938                // Experimental code to more aggressively collect pss while
17939                // running test...  the problem is that this tends to collect
17940                // the data right when a process is transitioning between process
17941                // states, which well tend to give noisy data.
17942                long start = SystemClock.uptimeMillis();
17943                long pss = Debug.getPss(app.pid, mTmpLong, null);
17944                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17945                mPendingPssProcesses.remove(app);
17946                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17947                        + " to " + app.curProcState + ": "
17948                        + (SystemClock.uptimeMillis()-start) + "ms");
17949            }
17950            app.lastStateTime = now;
17951            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17952                    mTestPssMode, isSleeping(), now);
17953            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17954                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17955                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17956                    + (app.nextPssTime-now) + ": " + app);
17957        } else {
17958            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17959                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17960                    mTestPssMode)))) {
17961                requestPssLocked(app, app.setProcState);
17962                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17963                        mTestPssMode, isSleeping(), now);
17964            } else if (false && DEBUG_PSS) {
17965                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17966            }
17967        }
17968        if (app.setProcState != app.curProcState) {
17969            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17970                    "Proc state change of " + app.processName
17971                    + " to " + app.curProcState);
17972            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17973            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17974            if (setImportant && !curImportant) {
17975                // This app is no longer something we consider important enough to allow to
17976                // use arbitrary amounts of battery power.  Note
17977                // its current wake lock time to later know to kill it if
17978                // it is not behaving well.
17979                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17980                synchronized (stats) {
17981                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17982                            app.pid, SystemClock.elapsedRealtime());
17983                }
17984                app.lastCpuTime = app.curCpuTime;
17985
17986            }
17987            app.setProcState = app.curProcState;
17988            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17989                app.notCachedSinceIdle = false;
17990            }
17991            if (!doingAll) {
17992                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17993            } else {
17994                app.procStateChanged = true;
17995            }
17996        }
17997
17998        if (changes != 0) {
17999            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18000            int i = mPendingProcessChanges.size()-1;
18001            ProcessChangeItem item = null;
18002            while (i >= 0) {
18003                item = mPendingProcessChanges.get(i);
18004                if (item.pid == app.pid) {
18005                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18006                    break;
18007                }
18008                i--;
18009            }
18010            if (i < 0) {
18011                // No existing item in pending changes; need a new one.
18012                final int NA = mAvailProcessChanges.size();
18013                if (NA > 0) {
18014                    item = mAvailProcessChanges.remove(NA-1);
18015                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18016                } else {
18017                    item = new ProcessChangeItem();
18018                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18019                }
18020                item.changes = 0;
18021                item.pid = app.pid;
18022                item.uid = app.info.uid;
18023                if (mPendingProcessChanges.size() == 0) {
18024                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18025                            "*** Enqueueing dispatch processes changed!");
18026                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18027                }
18028                mPendingProcessChanges.add(item);
18029            }
18030            item.changes |= changes;
18031            item.processState = app.repProcState;
18032            item.foregroundActivities = app.repForegroundActivities;
18033            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18034                    + Integer.toHexString(System.identityHashCode(item))
18035                    + " " + app.toShortString() + ": changes=" + item.changes
18036                    + " procState=" + item.processState
18037                    + " foreground=" + item.foregroundActivities
18038                    + " type=" + app.adjType + " source=" + app.adjSource
18039                    + " target=" + app.adjTarget);
18040        }
18041
18042        return success;
18043    }
18044
18045    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18046        if (proc.thread != null) {
18047            if (proc.baseProcessTracker != null) {
18048                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18049            }
18050            if (proc.repProcState >= 0) {
18051                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18052                        proc.repProcState);
18053            }
18054        }
18055    }
18056
18057    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18058            ProcessRecord TOP_APP, boolean doingAll, long now) {
18059        if (app.thread == null) {
18060            return false;
18061        }
18062
18063        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18064
18065        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18066    }
18067
18068    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18069            boolean oomAdj) {
18070        if (isForeground != proc.foregroundServices) {
18071            proc.foregroundServices = isForeground;
18072            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18073                    proc.info.uid);
18074            if (isForeground) {
18075                if (curProcs == null) {
18076                    curProcs = new ArrayList<ProcessRecord>();
18077                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18078                }
18079                if (!curProcs.contains(proc)) {
18080                    curProcs.add(proc);
18081                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18082                            proc.info.packageName, proc.info.uid);
18083                }
18084            } else {
18085                if (curProcs != null) {
18086                    if (curProcs.remove(proc)) {
18087                        mBatteryStatsService.noteEvent(
18088                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18089                                proc.info.packageName, proc.info.uid);
18090                        if (curProcs.size() <= 0) {
18091                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18092                        }
18093                    }
18094                }
18095            }
18096            if (oomAdj) {
18097                updateOomAdjLocked();
18098            }
18099        }
18100    }
18101
18102    private final ActivityRecord resumedAppLocked() {
18103        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18104        String pkg;
18105        int uid;
18106        if (act != null) {
18107            pkg = act.packageName;
18108            uid = act.info.applicationInfo.uid;
18109        } else {
18110            pkg = null;
18111            uid = -1;
18112        }
18113        // Has the UID or resumed package name changed?
18114        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18115                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18116            if (mCurResumedPackage != null) {
18117                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18118                        mCurResumedPackage, mCurResumedUid);
18119            }
18120            mCurResumedPackage = pkg;
18121            mCurResumedUid = uid;
18122            if (mCurResumedPackage != null) {
18123                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18124                        mCurResumedPackage, mCurResumedUid);
18125            }
18126        }
18127        return act;
18128    }
18129
18130    final boolean updateOomAdjLocked(ProcessRecord app) {
18131        final ActivityRecord TOP_ACT = resumedAppLocked();
18132        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18133        final boolean wasCached = app.cached;
18134
18135        mAdjSeq++;
18136
18137        // This is the desired cached adjusment we want to tell it to use.
18138        // If our app is currently cached, we know it, and that is it.  Otherwise,
18139        // we don't know it yet, and it needs to now be cached we will then
18140        // need to do a complete oom adj.
18141        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18142                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18143        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18144                SystemClock.uptimeMillis());
18145        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18146            // Changed to/from cached state, so apps after it in the LRU
18147            // list may also be changed.
18148            updateOomAdjLocked();
18149        }
18150        return success;
18151    }
18152
18153    final void updateOomAdjLocked() {
18154        final ActivityRecord TOP_ACT = resumedAppLocked();
18155        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18156        final long now = SystemClock.uptimeMillis();
18157        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18158        final int N = mLruProcesses.size();
18159
18160        if (false) {
18161            RuntimeException e = new RuntimeException();
18162            e.fillInStackTrace();
18163            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18164        }
18165
18166        mAdjSeq++;
18167        mNewNumServiceProcs = 0;
18168        mNewNumAServiceProcs = 0;
18169
18170        final int emptyProcessLimit;
18171        final int cachedProcessLimit;
18172        if (mProcessLimit <= 0) {
18173            emptyProcessLimit = cachedProcessLimit = 0;
18174        } else if (mProcessLimit == 1) {
18175            emptyProcessLimit = 1;
18176            cachedProcessLimit = 0;
18177        } else {
18178            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18179            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18180        }
18181
18182        // Let's determine how many processes we have running vs.
18183        // how many slots we have for background processes; we may want
18184        // to put multiple processes in a slot of there are enough of
18185        // them.
18186        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18187                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18188        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18189        if (numEmptyProcs > cachedProcessLimit) {
18190            // If there are more empty processes than our limit on cached
18191            // processes, then use the cached process limit for the factor.
18192            // This ensures that the really old empty processes get pushed
18193            // down to the bottom, so if we are running low on memory we will
18194            // have a better chance at keeping around more cached processes
18195            // instead of a gazillion empty processes.
18196            numEmptyProcs = cachedProcessLimit;
18197        }
18198        int emptyFactor = numEmptyProcs/numSlots;
18199        if (emptyFactor < 1) emptyFactor = 1;
18200        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18201        if (cachedFactor < 1) cachedFactor = 1;
18202        int stepCached = 0;
18203        int stepEmpty = 0;
18204        int numCached = 0;
18205        int numEmpty = 0;
18206        int numTrimming = 0;
18207
18208        mNumNonCachedProcs = 0;
18209        mNumCachedHiddenProcs = 0;
18210
18211        // First update the OOM adjustment for each of the
18212        // application processes based on their current state.
18213        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18214        int nextCachedAdj = curCachedAdj+1;
18215        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18216        int nextEmptyAdj = curEmptyAdj+2;
18217        for (int i=N-1; i>=0; i--) {
18218            ProcessRecord app = mLruProcesses.get(i);
18219            if (!app.killedByAm && app.thread != null) {
18220                app.procStateChanged = false;
18221                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18222
18223                // If we haven't yet assigned the final cached adj
18224                // to the process, do that now.
18225                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18226                    switch (app.curProcState) {
18227                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18228                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18229                            // This process is a cached process holding activities...
18230                            // assign it the next cached value for that type, and then
18231                            // step that cached level.
18232                            app.curRawAdj = curCachedAdj;
18233                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18234                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18235                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18236                                    + ")");
18237                            if (curCachedAdj != nextCachedAdj) {
18238                                stepCached++;
18239                                if (stepCached >= cachedFactor) {
18240                                    stepCached = 0;
18241                                    curCachedAdj = nextCachedAdj;
18242                                    nextCachedAdj += 2;
18243                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18244                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18245                                    }
18246                                }
18247                            }
18248                            break;
18249                        default:
18250                            // For everything else, assign next empty cached process
18251                            // level and bump that up.  Note that this means that
18252                            // long-running services that have dropped down to the
18253                            // cached level will be treated as empty (since their process
18254                            // state is still as a service), which is what we want.
18255                            app.curRawAdj = curEmptyAdj;
18256                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18257                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18258                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18259                                    + ")");
18260                            if (curEmptyAdj != nextEmptyAdj) {
18261                                stepEmpty++;
18262                                if (stepEmpty >= emptyFactor) {
18263                                    stepEmpty = 0;
18264                                    curEmptyAdj = nextEmptyAdj;
18265                                    nextEmptyAdj += 2;
18266                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18267                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18268                                    }
18269                                }
18270                            }
18271                            break;
18272                    }
18273                }
18274
18275                applyOomAdjLocked(app, TOP_APP, true, now);
18276
18277                // Count the number of process types.
18278                switch (app.curProcState) {
18279                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18280                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18281                        mNumCachedHiddenProcs++;
18282                        numCached++;
18283                        if (numCached > cachedProcessLimit) {
18284                            app.kill("cached #" + numCached, true);
18285                        }
18286                        break;
18287                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18288                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18289                                && app.lastActivityTime < oldTime) {
18290                            app.kill("empty for "
18291                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18292                                    / 1000) + "s", true);
18293                        } else {
18294                            numEmpty++;
18295                            if (numEmpty > emptyProcessLimit) {
18296                                app.kill("empty #" + numEmpty, true);
18297                            }
18298                        }
18299                        break;
18300                    default:
18301                        mNumNonCachedProcs++;
18302                        break;
18303                }
18304
18305                if (app.isolated && app.services.size() <= 0) {
18306                    // If this is an isolated process, and there are no
18307                    // services running in it, then the process is no longer
18308                    // needed.  We agressively kill these because we can by
18309                    // definition not re-use the same process again, and it is
18310                    // good to avoid having whatever code was running in them
18311                    // left sitting around after no longer needed.
18312                    app.kill("isolated not needed", true);
18313                }
18314
18315                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18316                        && !app.killedByAm) {
18317                    numTrimming++;
18318                }
18319            }
18320        }
18321
18322        mNumServiceProcs = mNewNumServiceProcs;
18323
18324        // Now determine the memory trimming level of background processes.
18325        // Unfortunately we need to start at the back of the list to do this
18326        // properly.  We only do this if the number of background apps we
18327        // are managing to keep around is less than half the maximum we desire;
18328        // if we are keeping a good number around, we'll let them use whatever
18329        // memory they want.
18330        final int numCachedAndEmpty = numCached + numEmpty;
18331        int memFactor;
18332        if (numCached <= ProcessList.TRIM_CACHED_APPS
18333                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18334            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18335                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18336            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18337                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18338            } else {
18339                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18340            }
18341        } else {
18342            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18343        }
18344        // We always allow the memory level to go up (better).  We only allow it to go
18345        // down if we are in a state where that is allowed, *and* the total number of processes
18346        // has gone down since last time.
18347        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18348                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18349                + " last=" + mLastNumProcesses);
18350        if (memFactor > mLastMemoryLevel) {
18351            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18352                memFactor = mLastMemoryLevel;
18353                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18354            }
18355        }
18356        mLastMemoryLevel = memFactor;
18357        mLastNumProcesses = mLruProcesses.size();
18358        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18359        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18360        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18361            if (mLowRamStartTime == 0) {
18362                mLowRamStartTime = now;
18363            }
18364            int step = 0;
18365            int fgTrimLevel;
18366            switch (memFactor) {
18367                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18368                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18369                    break;
18370                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18371                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18372                    break;
18373                default:
18374                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18375                    break;
18376            }
18377            int factor = numTrimming/3;
18378            int minFactor = 2;
18379            if (mHomeProcess != null) minFactor++;
18380            if (mPreviousProcess != null) minFactor++;
18381            if (factor < minFactor) factor = minFactor;
18382            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18383            for (int i=N-1; i>=0; i--) {
18384                ProcessRecord app = mLruProcesses.get(i);
18385                if (allChanged || app.procStateChanged) {
18386                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18387                    app.procStateChanged = false;
18388                }
18389                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18390                        && !app.killedByAm) {
18391                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18392                        try {
18393                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18394                                    "Trimming memory of " + app.processName
18395                                    + " to " + curLevel);
18396                            app.thread.scheduleTrimMemory(curLevel);
18397                        } catch (RemoteException e) {
18398                        }
18399                        if (false) {
18400                            // For now we won't do this; our memory trimming seems
18401                            // to be good enough at this point that destroying
18402                            // activities causes more harm than good.
18403                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18404                                    && app != mHomeProcess && app != mPreviousProcess) {
18405                                // Need to do this on its own message because the stack may not
18406                                // be in a consistent state at this point.
18407                                // For these apps we will also finish their activities
18408                                // to help them free memory.
18409                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18410                            }
18411                        }
18412                    }
18413                    app.trimMemoryLevel = curLevel;
18414                    step++;
18415                    if (step >= factor) {
18416                        step = 0;
18417                        switch (curLevel) {
18418                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18419                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18420                                break;
18421                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18422                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18423                                break;
18424                        }
18425                    }
18426                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18427                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18428                            && app.thread != null) {
18429                        try {
18430                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18431                                    "Trimming memory of heavy-weight " + app.processName
18432                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18433                            app.thread.scheduleTrimMemory(
18434                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18435                        } catch (RemoteException e) {
18436                        }
18437                    }
18438                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18439                } else {
18440                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18441                            || app.systemNoUi) && app.pendingUiClean) {
18442                        // If this application is now in the background and it
18443                        // had done UI, then give it the special trim level to
18444                        // have it free UI resources.
18445                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18446                        if (app.trimMemoryLevel < level && app.thread != null) {
18447                            try {
18448                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18449                                        "Trimming memory of bg-ui " + app.processName
18450                                        + " to " + level);
18451                                app.thread.scheduleTrimMemory(level);
18452                            } catch (RemoteException e) {
18453                            }
18454                        }
18455                        app.pendingUiClean = false;
18456                    }
18457                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18458                        try {
18459                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18460                                    "Trimming memory of fg " + app.processName
18461                                    + " to " + fgTrimLevel);
18462                            app.thread.scheduleTrimMemory(fgTrimLevel);
18463                        } catch (RemoteException e) {
18464                        }
18465                    }
18466                    app.trimMemoryLevel = fgTrimLevel;
18467                }
18468            }
18469        } else {
18470            if (mLowRamStartTime != 0) {
18471                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18472                mLowRamStartTime = 0;
18473            }
18474            for (int i=N-1; i>=0; i--) {
18475                ProcessRecord app = mLruProcesses.get(i);
18476                if (allChanged || app.procStateChanged) {
18477                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18478                    app.procStateChanged = false;
18479                }
18480                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18481                        || app.systemNoUi) && app.pendingUiClean) {
18482                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18483                            && app.thread != null) {
18484                        try {
18485                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18486                                    "Trimming memory of ui hidden " + app.processName
18487                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18488                            app.thread.scheduleTrimMemory(
18489                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18490                        } catch (RemoteException e) {
18491                        }
18492                    }
18493                    app.pendingUiClean = false;
18494                }
18495                app.trimMemoryLevel = 0;
18496            }
18497        }
18498
18499        if (mAlwaysFinishActivities) {
18500            // Need to do this on its own message because the stack may not
18501            // be in a consistent state at this point.
18502            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18503        }
18504
18505        if (allChanged) {
18506            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18507        }
18508
18509        if (mProcessStats.shouldWriteNowLocked(now)) {
18510            mHandler.post(new Runnable() {
18511                @Override public void run() {
18512                    synchronized (ActivityManagerService.this) {
18513                        mProcessStats.writeStateAsyncLocked();
18514                    }
18515                }
18516            });
18517        }
18518
18519        if (DEBUG_OOM_ADJ) {
18520            if (false) {
18521                RuntimeException here = new RuntimeException("here");
18522                here.fillInStackTrace();
18523                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18524            } else {
18525                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18526            }
18527        }
18528    }
18529
18530    final void trimApplications() {
18531        synchronized (this) {
18532            int i;
18533
18534            // First remove any unused application processes whose package
18535            // has been removed.
18536            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18537                final ProcessRecord app = mRemovedProcesses.get(i);
18538                if (app.activities.size() == 0
18539                        && app.curReceiver == null && app.services.size() == 0) {
18540                    Slog.i(
18541                        TAG, "Exiting empty application process "
18542                        + app.processName + " ("
18543                        + (app.thread != null ? app.thread.asBinder() : null)
18544                        + ")\n");
18545                    if (app.pid > 0 && app.pid != MY_PID) {
18546                        app.kill("empty", false);
18547                    } else {
18548                        try {
18549                            app.thread.scheduleExit();
18550                        } catch (Exception e) {
18551                            // Ignore exceptions.
18552                        }
18553                    }
18554                    cleanUpApplicationRecordLocked(app, false, true, -1);
18555                    mRemovedProcesses.remove(i);
18556
18557                    if (app.persistent) {
18558                        addAppLocked(app.info, false, null /* ABI override */);
18559                    }
18560                }
18561            }
18562
18563            // Now update the oom adj for all processes.
18564            updateOomAdjLocked();
18565        }
18566    }
18567
18568    /** This method sends the specified signal to each of the persistent apps */
18569    public void signalPersistentProcesses(int sig) throws RemoteException {
18570        if (sig != Process.SIGNAL_USR1) {
18571            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18572        }
18573
18574        synchronized (this) {
18575            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18576                    != PackageManager.PERMISSION_GRANTED) {
18577                throw new SecurityException("Requires permission "
18578                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18579            }
18580
18581            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18582                ProcessRecord r = mLruProcesses.get(i);
18583                if (r.thread != null && r.persistent) {
18584                    Process.sendSignal(r.pid, sig);
18585                }
18586            }
18587        }
18588    }
18589
18590    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18591        if (proc == null || proc == mProfileProc) {
18592            proc = mProfileProc;
18593            profileType = mProfileType;
18594            clearProfilerLocked();
18595        }
18596        if (proc == null) {
18597            return;
18598        }
18599        try {
18600            proc.thread.profilerControl(false, null, profileType);
18601        } catch (RemoteException e) {
18602            throw new IllegalStateException("Process disappeared");
18603        }
18604    }
18605
18606    private void clearProfilerLocked() {
18607        if (mProfileFd != null) {
18608            try {
18609                mProfileFd.close();
18610            } catch (IOException e) {
18611            }
18612        }
18613        mProfileApp = null;
18614        mProfileProc = null;
18615        mProfileFile = null;
18616        mProfileType = 0;
18617        mAutoStopProfiler = false;
18618        mSamplingInterval = 0;
18619    }
18620
18621    public boolean profileControl(String process, int userId, boolean start,
18622            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18623
18624        try {
18625            synchronized (this) {
18626                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18627                // its own permission.
18628                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18629                        != PackageManager.PERMISSION_GRANTED) {
18630                    throw new SecurityException("Requires permission "
18631                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18632                }
18633
18634                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18635                    throw new IllegalArgumentException("null profile info or fd");
18636                }
18637
18638                ProcessRecord proc = null;
18639                if (process != null) {
18640                    proc = findProcessLocked(process, userId, "profileControl");
18641                }
18642
18643                if (start && (proc == null || proc.thread == null)) {
18644                    throw new IllegalArgumentException("Unknown process: " + process);
18645                }
18646
18647                if (start) {
18648                    stopProfilerLocked(null, 0);
18649                    setProfileApp(proc.info, proc.processName, profilerInfo);
18650                    mProfileProc = proc;
18651                    mProfileType = profileType;
18652                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18653                    try {
18654                        fd = fd.dup();
18655                    } catch (IOException e) {
18656                        fd = null;
18657                    }
18658                    profilerInfo.profileFd = fd;
18659                    proc.thread.profilerControl(start, profilerInfo, profileType);
18660                    fd = null;
18661                    mProfileFd = null;
18662                } else {
18663                    stopProfilerLocked(proc, profileType);
18664                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18665                        try {
18666                            profilerInfo.profileFd.close();
18667                        } catch (IOException e) {
18668                        }
18669                    }
18670                }
18671
18672                return true;
18673            }
18674        } catch (RemoteException e) {
18675            throw new IllegalStateException("Process disappeared");
18676        } finally {
18677            if (profilerInfo != null && profilerInfo.profileFd != null) {
18678                try {
18679                    profilerInfo.profileFd.close();
18680                } catch (IOException e) {
18681                }
18682            }
18683        }
18684    }
18685
18686    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18687        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18688                userId, true, ALLOW_FULL_ONLY, callName, null);
18689        ProcessRecord proc = null;
18690        try {
18691            int pid = Integer.parseInt(process);
18692            synchronized (mPidsSelfLocked) {
18693                proc = mPidsSelfLocked.get(pid);
18694            }
18695        } catch (NumberFormatException e) {
18696        }
18697
18698        if (proc == null) {
18699            ArrayMap<String, SparseArray<ProcessRecord>> all
18700                    = mProcessNames.getMap();
18701            SparseArray<ProcessRecord> procs = all.get(process);
18702            if (procs != null && procs.size() > 0) {
18703                proc = procs.valueAt(0);
18704                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18705                    for (int i=1; i<procs.size(); i++) {
18706                        ProcessRecord thisProc = procs.valueAt(i);
18707                        if (thisProc.userId == userId) {
18708                            proc = thisProc;
18709                            break;
18710                        }
18711                    }
18712                }
18713            }
18714        }
18715
18716        return proc;
18717    }
18718
18719    public boolean dumpHeap(String process, int userId, boolean managed,
18720            String path, ParcelFileDescriptor fd) throws RemoteException {
18721
18722        try {
18723            synchronized (this) {
18724                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18725                // its own permission (same as profileControl).
18726                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18727                        != PackageManager.PERMISSION_GRANTED) {
18728                    throw new SecurityException("Requires permission "
18729                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18730                }
18731
18732                if (fd == null) {
18733                    throw new IllegalArgumentException("null fd");
18734                }
18735
18736                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18737                if (proc == null || proc.thread == null) {
18738                    throw new IllegalArgumentException("Unknown process: " + process);
18739                }
18740
18741                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18742                if (!isDebuggable) {
18743                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18744                        throw new SecurityException("Process not debuggable: " + proc);
18745                    }
18746                }
18747
18748                proc.thread.dumpHeap(managed, path, fd);
18749                fd = null;
18750                return true;
18751            }
18752        } catch (RemoteException e) {
18753            throw new IllegalStateException("Process disappeared");
18754        } finally {
18755            if (fd != null) {
18756                try {
18757                    fd.close();
18758                } catch (IOException e) {
18759                }
18760            }
18761        }
18762    }
18763
18764    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18765    public void monitor() {
18766        synchronized (this) { }
18767    }
18768
18769    void onCoreSettingsChange(Bundle settings) {
18770        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18771            ProcessRecord processRecord = mLruProcesses.get(i);
18772            try {
18773                if (processRecord.thread != null) {
18774                    processRecord.thread.setCoreSettings(settings);
18775                }
18776            } catch (RemoteException re) {
18777                /* ignore */
18778            }
18779        }
18780    }
18781
18782    // Multi-user methods
18783
18784    /**
18785     * Start user, if its not already running, but don't bring it to foreground.
18786     */
18787    @Override
18788    public boolean startUserInBackground(final int userId) {
18789        return startUser(userId, /* foreground */ false);
18790    }
18791
18792    /**
18793     * Start user, if its not already running, and bring it to foreground.
18794     */
18795    boolean startUserInForeground(final int userId, Dialog dlg) {
18796        boolean result = startUser(userId, /* foreground */ true);
18797        dlg.dismiss();
18798        return result;
18799    }
18800
18801    /**
18802     * Refreshes the list of users related to the current user when either a
18803     * user switch happens or when a new related user is started in the
18804     * background.
18805     */
18806    private void updateCurrentProfileIdsLocked() {
18807        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18808                mCurrentUserId, false /* enabledOnly */);
18809        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18810        for (int i = 0; i < currentProfileIds.length; i++) {
18811            currentProfileIds[i] = profiles.get(i).id;
18812        }
18813        mCurrentProfileIds = currentProfileIds;
18814
18815        synchronized (mUserProfileGroupIdsSelfLocked) {
18816            mUserProfileGroupIdsSelfLocked.clear();
18817            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18818            for (int i = 0; i < users.size(); i++) {
18819                UserInfo user = users.get(i);
18820                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18821                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18822                }
18823            }
18824        }
18825    }
18826
18827    private Set getProfileIdsLocked(int userId) {
18828        Set userIds = new HashSet<Integer>();
18829        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18830                userId, false /* enabledOnly */);
18831        for (UserInfo user : profiles) {
18832            userIds.add(Integer.valueOf(user.id));
18833        }
18834        return userIds;
18835    }
18836
18837    @Override
18838    public boolean switchUser(final int userId) {
18839        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18840        String userName;
18841        synchronized (this) {
18842            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18843            if (userInfo == null) {
18844                Slog.w(TAG, "No user info for user #" + userId);
18845                return false;
18846            }
18847            if (userInfo.isManagedProfile()) {
18848                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18849                return false;
18850            }
18851            userName = userInfo.name;
18852            mTargetUserId = userId;
18853        }
18854        mHandler.removeMessages(START_USER_SWITCH_MSG);
18855        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18856        return true;
18857    }
18858
18859    private void showUserSwitchDialog(int userId, String userName) {
18860        // The dialog will show and then initiate the user switch by calling startUserInForeground
18861        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18862                true /* above system */);
18863        d.show();
18864    }
18865
18866    private boolean startUser(final int userId, final boolean foreground) {
18867        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18868                != PackageManager.PERMISSION_GRANTED) {
18869            String msg = "Permission Denial: switchUser() from pid="
18870                    + Binder.getCallingPid()
18871                    + ", uid=" + Binder.getCallingUid()
18872                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18873            Slog.w(TAG, msg);
18874            throw new SecurityException(msg);
18875        }
18876
18877        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18878
18879        final long ident = Binder.clearCallingIdentity();
18880        try {
18881            synchronized (this) {
18882                final int oldUserId = mCurrentUserId;
18883                if (oldUserId == userId) {
18884                    return true;
18885                }
18886
18887                mStackSupervisor.setLockTaskModeLocked(null, false);
18888
18889                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18890                if (userInfo == null) {
18891                    Slog.w(TAG, "No user info for user #" + userId);
18892                    return false;
18893                }
18894                if (foreground && userInfo.isManagedProfile()) {
18895                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18896                    return false;
18897                }
18898
18899                if (foreground) {
18900                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18901                            R.anim.screen_user_enter);
18902                }
18903
18904                boolean needStart = false;
18905
18906                // If the user we are switching to is not currently started, then
18907                // we need to start it now.
18908                if (mStartedUsers.get(userId) == null) {
18909                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18910                    updateStartedUserArrayLocked();
18911                    needStart = true;
18912                }
18913
18914                final Integer userIdInt = Integer.valueOf(userId);
18915                mUserLru.remove(userIdInt);
18916                mUserLru.add(userIdInt);
18917
18918                if (foreground) {
18919                    mCurrentUserId = userId;
18920                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18921                    updateCurrentProfileIdsLocked();
18922                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18923                    // Once the internal notion of the active user has switched, we lock the device
18924                    // with the option to show the user switcher on the keyguard.
18925                    mWindowManager.lockNow(null);
18926                } else {
18927                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18928                    updateCurrentProfileIdsLocked();
18929                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18930                    mUserLru.remove(currentUserIdInt);
18931                    mUserLru.add(currentUserIdInt);
18932                }
18933
18934                final UserStartedState uss = mStartedUsers.get(userId);
18935
18936                // Make sure user is in the started state.  If it is currently
18937                // stopping, we need to knock that off.
18938                if (uss.mState == UserStartedState.STATE_STOPPING) {
18939                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18940                    // so we can just fairly silently bring the user back from
18941                    // the almost-dead.
18942                    uss.mState = UserStartedState.STATE_RUNNING;
18943                    updateStartedUserArrayLocked();
18944                    needStart = true;
18945                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18946                    // This means ACTION_SHUTDOWN has been sent, so we will
18947                    // need to treat this as a new boot of the user.
18948                    uss.mState = UserStartedState.STATE_BOOTING;
18949                    updateStartedUserArrayLocked();
18950                    needStart = true;
18951                }
18952
18953                if (uss.mState == UserStartedState.STATE_BOOTING) {
18954                    // Booting up a new user, need to tell system services about it.
18955                    // Note that this is on the same handler as scheduling of broadcasts,
18956                    // which is important because it needs to go first.
18957                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18958                }
18959
18960                if (foreground) {
18961                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18962                            oldUserId));
18963                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18964                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18965                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18966                            oldUserId, userId, uss));
18967                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18968                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18969                }
18970
18971                if (needStart) {
18972                    // Send USER_STARTED broadcast
18973                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18974                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18975                            | Intent.FLAG_RECEIVER_FOREGROUND);
18976                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18977                    broadcastIntentLocked(null, null, intent,
18978                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18979                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18980                }
18981
18982                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18983                    if (userId != UserHandle.USER_OWNER) {
18984                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18985                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18986                        broadcastIntentLocked(null, null, intent, null,
18987                                new IIntentReceiver.Stub() {
18988                                    public void performReceive(Intent intent, int resultCode,
18989                                            String data, Bundle extras, boolean ordered,
18990                                            boolean sticky, int sendingUser) {
18991                                        onUserInitialized(uss, foreground, oldUserId, userId);
18992                                    }
18993                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18994                                true, false, MY_PID, Process.SYSTEM_UID,
18995                                userId);
18996                        uss.initializing = true;
18997                    } else {
18998                        getUserManagerLocked().makeInitialized(userInfo.id);
18999                    }
19000                }
19001
19002                if (foreground) {
19003                    if (!uss.initializing) {
19004                        moveUserToForeground(uss, oldUserId, userId);
19005                    }
19006                } else {
19007                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19008                }
19009
19010                if (needStart) {
19011                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19012                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19013                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19014                    broadcastIntentLocked(null, null, intent,
19015                            null, new IIntentReceiver.Stub() {
19016                                @Override
19017                                public void performReceive(Intent intent, int resultCode, String data,
19018                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19019                                        throws RemoteException {
19020                                }
19021                            }, 0, null, null,
19022                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19023                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19024                }
19025            }
19026        } finally {
19027            Binder.restoreCallingIdentity(ident);
19028        }
19029
19030        return true;
19031    }
19032
19033    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19034        long ident = Binder.clearCallingIdentity();
19035        try {
19036            Intent intent;
19037            if (oldUserId >= 0) {
19038                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19039                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19040                int count = profiles.size();
19041                for (int i = 0; i < count; i++) {
19042                    int profileUserId = profiles.get(i).id;
19043                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19044                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19045                            | Intent.FLAG_RECEIVER_FOREGROUND);
19046                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19047                    broadcastIntentLocked(null, null, intent,
19048                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19049                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19050                }
19051            }
19052            if (newUserId >= 0) {
19053                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19054                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19055                int count = profiles.size();
19056                for (int i = 0; i < count; i++) {
19057                    int profileUserId = profiles.get(i).id;
19058                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19059                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19060                            | Intent.FLAG_RECEIVER_FOREGROUND);
19061                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19062                    broadcastIntentLocked(null, null, intent,
19063                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19064                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19065                }
19066                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19067                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19068                        | Intent.FLAG_RECEIVER_FOREGROUND);
19069                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19070                broadcastIntentLocked(null, null, intent,
19071                        null, null, 0, null, null,
19072                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19073                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19074            }
19075        } finally {
19076            Binder.restoreCallingIdentity(ident);
19077        }
19078    }
19079
19080    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19081            final int newUserId) {
19082        final int N = mUserSwitchObservers.beginBroadcast();
19083        if (N > 0) {
19084            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19085                int mCount = 0;
19086                @Override
19087                public void sendResult(Bundle data) throws RemoteException {
19088                    synchronized (ActivityManagerService.this) {
19089                        if (mCurUserSwitchCallback == this) {
19090                            mCount++;
19091                            if (mCount == N) {
19092                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19093                            }
19094                        }
19095                    }
19096                }
19097            };
19098            synchronized (this) {
19099                uss.switching = true;
19100                mCurUserSwitchCallback = callback;
19101            }
19102            for (int i=0; i<N; i++) {
19103                try {
19104                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19105                            newUserId, callback);
19106                } catch (RemoteException e) {
19107                }
19108            }
19109        } else {
19110            synchronized (this) {
19111                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19112            }
19113        }
19114        mUserSwitchObservers.finishBroadcast();
19115    }
19116
19117    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19118        synchronized (this) {
19119            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19120            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19121        }
19122    }
19123
19124    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19125        mCurUserSwitchCallback = null;
19126        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19127        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19128                oldUserId, newUserId, uss));
19129    }
19130
19131    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19132        synchronized (this) {
19133            if (foreground) {
19134                moveUserToForeground(uss, oldUserId, newUserId);
19135            }
19136        }
19137
19138        completeSwitchAndInitalize(uss, newUserId, true, false);
19139    }
19140
19141    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19142        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19143        if (homeInFront) {
19144            startHomeActivityLocked(newUserId);
19145        } else {
19146            mStackSupervisor.resumeTopActivitiesLocked();
19147        }
19148        EventLogTags.writeAmSwitchUser(newUserId);
19149        getUserManagerLocked().userForeground(newUserId);
19150        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19151    }
19152
19153    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19154        completeSwitchAndInitalize(uss, newUserId, false, true);
19155    }
19156
19157    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19158            boolean clearInitializing, boolean clearSwitching) {
19159        boolean unfrozen = false;
19160        synchronized (this) {
19161            if (clearInitializing) {
19162                uss.initializing = false;
19163                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19164            }
19165            if (clearSwitching) {
19166                uss.switching = false;
19167            }
19168            if (!uss.switching && !uss.initializing) {
19169                mWindowManager.stopFreezingScreen();
19170                unfrozen = true;
19171            }
19172        }
19173        if (unfrozen) {
19174            final int N = mUserSwitchObservers.beginBroadcast();
19175            for (int i=0; i<N; i++) {
19176                try {
19177                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19178                } catch (RemoteException e) {
19179                }
19180            }
19181            mUserSwitchObservers.finishBroadcast();
19182        }
19183        stopGuestUserIfBackground();
19184    }
19185
19186    /**
19187     * Stops the guest user if it has gone to the background.
19188     */
19189    private void stopGuestUserIfBackground() {
19190        synchronized (this) {
19191            final int num = mUserLru.size();
19192            for (int i = 0; i < num; i++) {
19193                Integer oldUserId = mUserLru.get(i);
19194                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19195                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19196                        || oldUss.mState == UserStartedState.STATE_STOPPING
19197                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19198                    continue;
19199                }
19200                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19201                if (userInfo.isGuest()) {
19202                    // This is a user to be stopped.
19203                    stopUserLocked(oldUserId, null);
19204                    break;
19205                }
19206            }
19207        }
19208    }
19209
19210    void scheduleStartProfilesLocked() {
19211        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19212            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19213                    DateUtils.SECOND_IN_MILLIS);
19214        }
19215    }
19216
19217    void startProfilesLocked() {
19218        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19219        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19220                mCurrentUserId, false /* enabledOnly */);
19221        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19222        for (UserInfo user : profiles) {
19223            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19224                    && user.id != mCurrentUserId) {
19225                toStart.add(user);
19226            }
19227        }
19228        final int n = toStart.size();
19229        int i = 0;
19230        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19231            startUserInBackground(toStart.get(i).id);
19232        }
19233        if (i < n) {
19234            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19235        }
19236    }
19237
19238    void finishUserBoot(UserStartedState uss) {
19239        synchronized (this) {
19240            if (uss.mState == UserStartedState.STATE_BOOTING
19241                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19242                uss.mState = UserStartedState.STATE_RUNNING;
19243                final int userId = uss.mHandle.getIdentifier();
19244                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19245                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19246                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19247                broadcastIntentLocked(null, null, intent,
19248                        null, null, 0, null, null,
19249                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19250                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19251            }
19252        }
19253    }
19254
19255    void finishUserSwitch(UserStartedState uss) {
19256        synchronized (this) {
19257            finishUserBoot(uss);
19258
19259            startProfilesLocked();
19260
19261            int num = mUserLru.size();
19262            int i = 0;
19263            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19264                Integer oldUserId = mUserLru.get(i);
19265                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19266                if (oldUss == null) {
19267                    // Shouldn't happen, but be sane if it does.
19268                    mUserLru.remove(i);
19269                    num--;
19270                    continue;
19271                }
19272                if (oldUss.mState == UserStartedState.STATE_STOPPING
19273                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19274                    // This user is already stopping, doesn't count.
19275                    num--;
19276                    i++;
19277                    continue;
19278                }
19279                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19280                    // Owner and current can't be stopped, but count as running.
19281                    i++;
19282                    continue;
19283                }
19284                // This is a user to be stopped.
19285                stopUserLocked(oldUserId, null);
19286                num--;
19287                i++;
19288            }
19289        }
19290    }
19291
19292    @Override
19293    public int stopUser(final int userId, final IStopUserCallback callback) {
19294        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19295                != PackageManager.PERMISSION_GRANTED) {
19296            String msg = "Permission Denial: switchUser() from pid="
19297                    + Binder.getCallingPid()
19298                    + ", uid=" + Binder.getCallingUid()
19299                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19300            Slog.w(TAG, msg);
19301            throw new SecurityException(msg);
19302        }
19303        if (userId <= 0) {
19304            throw new IllegalArgumentException("Can't stop primary user " + userId);
19305        }
19306        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19307        synchronized (this) {
19308            return stopUserLocked(userId, callback);
19309        }
19310    }
19311
19312    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19313        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19314        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19315            return ActivityManager.USER_OP_IS_CURRENT;
19316        }
19317
19318        final UserStartedState uss = mStartedUsers.get(userId);
19319        if (uss == null) {
19320            // User is not started, nothing to do...  but we do need to
19321            // callback if requested.
19322            if (callback != null) {
19323                mHandler.post(new Runnable() {
19324                    @Override
19325                    public void run() {
19326                        try {
19327                            callback.userStopped(userId);
19328                        } catch (RemoteException e) {
19329                        }
19330                    }
19331                });
19332            }
19333            return ActivityManager.USER_OP_SUCCESS;
19334        }
19335
19336        if (callback != null) {
19337            uss.mStopCallbacks.add(callback);
19338        }
19339
19340        if (uss.mState != UserStartedState.STATE_STOPPING
19341                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19342            uss.mState = UserStartedState.STATE_STOPPING;
19343            updateStartedUserArrayLocked();
19344
19345            long ident = Binder.clearCallingIdentity();
19346            try {
19347                // We are going to broadcast ACTION_USER_STOPPING and then
19348                // once that is done send a final ACTION_SHUTDOWN and then
19349                // stop the user.
19350                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19351                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19352                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19353                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19354                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19355                // This is the result receiver for the final shutdown broadcast.
19356                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19357                    @Override
19358                    public void performReceive(Intent intent, int resultCode, String data,
19359                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19360                        finishUserStop(uss);
19361                    }
19362                };
19363                // This is the result receiver for the initial stopping broadcast.
19364                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19365                    @Override
19366                    public void performReceive(Intent intent, int resultCode, String data,
19367                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19368                        // On to the next.
19369                        synchronized (ActivityManagerService.this) {
19370                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19371                                // Whoops, we are being started back up.  Abort, abort!
19372                                return;
19373                            }
19374                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19375                        }
19376                        mBatteryStatsService.noteEvent(
19377                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19378                                Integer.toString(userId), userId);
19379                        mSystemServiceManager.stopUser(userId);
19380                        broadcastIntentLocked(null, null, shutdownIntent,
19381                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19382                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19383                    }
19384                };
19385                // Kick things off.
19386                broadcastIntentLocked(null, null, stoppingIntent,
19387                        null, stoppingReceiver, 0, null, null,
19388                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19389                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19390            } finally {
19391                Binder.restoreCallingIdentity(ident);
19392            }
19393        }
19394
19395        return ActivityManager.USER_OP_SUCCESS;
19396    }
19397
19398    void finishUserStop(UserStartedState uss) {
19399        final int userId = uss.mHandle.getIdentifier();
19400        boolean stopped;
19401        ArrayList<IStopUserCallback> callbacks;
19402        synchronized (this) {
19403            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19404            if (mStartedUsers.get(userId) != uss) {
19405                stopped = false;
19406            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19407                stopped = false;
19408            } else {
19409                stopped = true;
19410                // User can no longer run.
19411                mStartedUsers.remove(userId);
19412                mUserLru.remove(Integer.valueOf(userId));
19413                updateStartedUserArrayLocked();
19414
19415                // Clean up all state and processes associated with the user.
19416                // Kill all the processes for the user.
19417                forceStopUserLocked(userId, "finish user");
19418            }
19419
19420            // Explicitly remove the old information in mRecentTasks.
19421            removeRecentTasksForUserLocked(userId);
19422        }
19423
19424        for (int i=0; i<callbacks.size(); i++) {
19425            try {
19426                if (stopped) callbacks.get(i).userStopped(userId);
19427                else callbacks.get(i).userStopAborted(userId);
19428            } catch (RemoteException e) {
19429            }
19430        }
19431
19432        if (stopped) {
19433            mSystemServiceManager.cleanupUser(userId);
19434            synchronized (this) {
19435                mStackSupervisor.removeUserLocked(userId);
19436            }
19437        }
19438    }
19439
19440    @Override
19441    public UserInfo getCurrentUser() {
19442        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19443                != PackageManager.PERMISSION_GRANTED) && (
19444                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19445                != PackageManager.PERMISSION_GRANTED)) {
19446            String msg = "Permission Denial: getCurrentUser() from pid="
19447                    + Binder.getCallingPid()
19448                    + ", uid=" + Binder.getCallingUid()
19449                    + " requires " + INTERACT_ACROSS_USERS;
19450            Slog.w(TAG, msg);
19451            throw new SecurityException(msg);
19452        }
19453        synchronized (this) {
19454            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19455            return getUserManagerLocked().getUserInfo(userId);
19456        }
19457    }
19458
19459    int getCurrentUserIdLocked() {
19460        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19461    }
19462
19463    @Override
19464    public boolean isUserRunning(int userId, boolean orStopped) {
19465        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19466                != PackageManager.PERMISSION_GRANTED) {
19467            String msg = "Permission Denial: isUserRunning() from pid="
19468                    + Binder.getCallingPid()
19469                    + ", uid=" + Binder.getCallingUid()
19470                    + " requires " + INTERACT_ACROSS_USERS;
19471            Slog.w(TAG, msg);
19472            throw new SecurityException(msg);
19473        }
19474        synchronized (this) {
19475            return isUserRunningLocked(userId, orStopped);
19476        }
19477    }
19478
19479    boolean isUserRunningLocked(int userId, boolean orStopped) {
19480        UserStartedState state = mStartedUsers.get(userId);
19481        if (state == null) {
19482            return false;
19483        }
19484        if (orStopped) {
19485            return true;
19486        }
19487        return state.mState != UserStartedState.STATE_STOPPING
19488                && state.mState != UserStartedState.STATE_SHUTDOWN;
19489    }
19490
19491    @Override
19492    public int[] getRunningUserIds() {
19493        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19494                != PackageManager.PERMISSION_GRANTED) {
19495            String msg = "Permission Denial: isUserRunning() from pid="
19496                    + Binder.getCallingPid()
19497                    + ", uid=" + Binder.getCallingUid()
19498                    + " requires " + INTERACT_ACROSS_USERS;
19499            Slog.w(TAG, msg);
19500            throw new SecurityException(msg);
19501        }
19502        synchronized (this) {
19503            return mStartedUserArray;
19504        }
19505    }
19506
19507    private void updateStartedUserArrayLocked() {
19508        int num = 0;
19509        for (int i=0; i<mStartedUsers.size();  i++) {
19510            UserStartedState uss = mStartedUsers.valueAt(i);
19511            // This list does not include stopping users.
19512            if (uss.mState != UserStartedState.STATE_STOPPING
19513                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19514                num++;
19515            }
19516        }
19517        mStartedUserArray = new int[num];
19518        num = 0;
19519        for (int i=0; i<mStartedUsers.size();  i++) {
19520            UserStartedState uss = mStartedUsers.valueAt(i);
19521            if (uss.mState != UserStartedState.STATE_STOPPING
19522                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19523                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19524                num++;
19525            }
19526        }
19527    }
19528
19529    @Override
19530    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19531        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19532                != PackageManager.PERMISSION_GRANTED) {
19533            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19534                    + Binder.getCallingPid()
19535                    + ", uid=" + Binder.getCallingUid()
19536                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19537            Slog.w(TAG, msg);
19538            throw new SecurityException(msg);
19539        }
19540
19541        mUserSwitchObservers.register(observer);
19542    }
19543
19544    @Override
19545    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19546        mUserSwitchObservers.unregister(observer);
19547    }
19548
19549    private boolean userExists(int userId) {
19550        if (userId == 0) {
19551            return true;
19552        }
19553        UserManagerService ums = getUserManagerLocked();
19554        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19555    }
19556
19557    int[] getUsersLocked() {
19558        UserManagerService ums = getUserManagerLocked();
19559        return ums != null ? ums.getUserIds() : new int[] { 0 };
19560    }
19561
19562    UserManagerService getUserManagerLocked() {
19563        if (mUserManager == null) {
19564            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19565            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19566        }
19567        return mUserManager;
19568    }
19569
19570    private int applyUserId(int uid, int userId) {
19571        return UserHandle.getUid(userId, uid);
19572    }
19573
19574    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19575        if (info == null) return null;
19576        ApplicationInfo newInfo = new ApplicationInfo(info);
19577        newInfo.uid = applyUserId(info.uid, userId);
19578        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19579                + info.packageName;
19580        return newInfo;
19581    }
19582
19583    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19584        if (aInfo == null
19585                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19586            return aInfo;
19587        }
19588
19589        ActivityInfo info = new ActivityInfo(aInfo);
19590        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19591        return info;
19592    }
19593
19594    private final class LocalService extends ActivityManagerInternal {
19595        @Override
19596        public void onWakefulnessChanged(int wakefulness) {
19597            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19598        }
19599
19600        @Override
19601        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19602                String processName, String abiOverride, int uid, Runnable crashHandler) {
19603            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19604                    processName, abiOverride, uid, crashHandler);
19605        }
19606    }
19607
19608    /**
19609     * An implementation of IAppTask, that allows an app to manage its own tasks via
19610     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19611     * only the process that calls getAppTasks() can call the AppTask methods.
19612     */
19613    class AppTaskImpl extends IAppTask.Stub {
19614        private int mTaskId;
19615        private int mCallingUid;
19616
19617        public AppTaskImpl(int taskId, int callingUid) {
19618            mTaskId = taskId;
19619            mCallingUid = callingUid;
19620        }
19621
19622        private void checkCaller() {
19623            if (mCallingUid != Binder.getCallingUid()) {
19624                throw new SecurityException("Caller " + mCallingUid
19625                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19626            }
19627        }
19628
19629        @Override
19630        public void finishAndRemoveTask() {
19631            checkCaller();
19632
19633            synchronized (ActivityManagerService.this) {
19634                long origId = Binder.clearCallingIdentity();
19635                try {
19636                    if (!removeTaskByIdLocked(mTaskId, false)) {
19637                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19638                    }
19639                } finally {
19640                    Binder.restoreCallingIdentity(origId);
19641                }
19642            }
19643        }
19644
19645        @Override
19646        public ActivityManager.RecentTaskInfo getTaskInfo() {
19647            checkCaller();
19648
19649            synchronized (ActivityManagerService.this) {
19650                long origId = Binder.clearCallingIdentity();
19651                try {
19652                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19653                    if (tr == null) {
19654                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19655                    }
19656                    return createRecentTaskInfoFromTaskRecord(tr);
19657                } finally {
19658                    Binder.restoreCallingIdentity(origId);
19659                }
19660            }
19661        }
19662
19663        @Override
19664        public void moveToFront() {
19665            checkCaller();
19666
19667            final TaskRecord tr;
19668            synchronized (ActivityManagerService.this) {
19669                tr = recentTaskForIdLocked(mTaskId);
19670                if (tr == null) {
19671                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19672                }
19673                if (tr.getRootActivity() != null) {
19674                    moveTaskToFrontLocked(tr.taskId, 0, null);
19675                    return;
19676                }
19677            }
19678
19679            startActivityFromRecentsInner(tr.taskId, null);
19680        }
19681
19682        @Override
19683        public int startActivity(IBinder whoThread, String callingPackage,
19684                Intent intent, String resolvedType, Bundle options) {
19685            checkCaller();
19686
19687            int callingUser = UserHandle.getCallingUserId();
19688            TaskRecord tr;
19689            IApplicationThread appThread;
19690            synchronized (ActivityManagerService.this) {
19691                tr = recentTaskForIdLocked(mTaskId);
19692                if (tr == null) {
19693                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19694                }
19695                appThread = ApplicationThreadNative.asInterface(whoThread);
19696                if (appThread == null) {
19697                    throw new IllegalArgumentException("Bad app thread " + appThread);
19698                }
19699            }
19700            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19701                    resolvedType, null, null, null, null, 0, 0, null, null,
19702                    null, options, callingUser, null, tr);
19703        }
19704
19705        @Override
19706        public void setExcludeFromRecents(boolean exclude) {
19707            checkCaller();
19708
19709            synchronized (ActivityManagerService.this) {
19710                long origId = Binder.clearCallingIdentity();
19711                try {
19712                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19713                    if (tr == null) {
19714                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19715                    }
19716                    Intent intent = tr.getBaseIntent();
19717                    if (exclude) {
19718                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19719                    } else {
19720                        intent.setFlags(intent.getFlags()
19721                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19722                    }
19723                } finally {
19724                    Binder.restoreCallingIdentity(origId);
19725                }
19726            }
19727        }
19728    }
19729}
19730