ActivityManagerService.java revision 299f960e5e5837da44cd81692388f3cbd5d2c362
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    final static class Association {
753        final int mSourceUid;
754        final String mSourceProcess;
755        final int mTargetUid;
756        final ComponentName mTargetComponent;
757        final String mTargetProcess;
758
759        int mCount;
760        long mTime;
761
762        int mNesting;
763        long mStartTime;
764
765        Association(int sourceUid, String sourceProcess, int targetUid,
766                ComponentName targetComponent, String targetProcess) {
767            mSourceUid = sourceUid;
768            mSourceProcess = sourceProcess;
769            mTargetUid = targetUid;
770            mTargetComponent = targetComponent;
771            mTargetProcess = targetProcess;
772        }
773    }
774
775    /**
776     * When service association tracking is enabled, this is all of the associations we
777     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
778     * -> association data.
779     */
780    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
781            mAssociations = new SparseArray<>();
782    boolean mTrackingAssociations;
783
784    /**
785     * Backup/restore process management
786     */
787    String mBackupAppName = null;
788    BackupRecord mBackupTarget = null;
789
790    final ProviderMap mProviderMap;
791
792    /**
793     * List of content providers who have clients waiting for them.  The
794     * application is currently being launched and the provider will be
795     * removed from this list once it is published.
796     */
797    final ArrayList<ContentProviderRecord> mLaunchingProviders
798            = new ArrayList<ContentProviderRecord>();
799
800    /**
801     * File storing persisted {@link #mGrantedUriPermissions}.
802     */
803    private final AtomicFile mGrantFile;
804
805    /** XML constants used in {@link #mGrantFile} */
806    private static final String TAG_URI_GRANTS = "uri-grants";
807    private static final String TAG_URI_GRANT = "uri-grant";
808    private static final String ATTR_USER_HANDLE = "userHandle";
809    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
810    private static final String ATTR_TARGET_USER_ID = "targetUserId";
811    private static final String ATTR_SOURCE_PKG = "sourcePkg";
812    private static final String ATTR_TARGET_PKG = "targetPkg";
813    private static final String ATTR_URI = "uri";
814    private static final String ATTR_MODE_FLAGS = "modeFlags";
815    private static final String ATTR_CREATED_TIME = "createdTime";
816    private static final String ATTR_PREFIX = "prefix";
817
818    /**
819     * Global set of specific {@link Uri} permissions that have been granted.
820     * This optimized lookup structure maps from {@link UriPermission#targetUid}
821     * to {@link UriPermission#uri} to {@link UriPermission}.
822     */
823    @GuardedBy("this")
824    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
825            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
826
827    public static class GrantUri {
828        public final int sourceUserId;
829        public final Uri uri;
830        public boolean prefix;
831
832        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
833            this.sourceUserId = sourceUserId;
834            this.uri = uri;
835            this.prefix = prefix;
836        }
837
838        @Override
839        public int hashCode() {
840            int hashCode = 1;
841            hashCode = 31 * hashCode + sourceUserId;
842            hashCode = 31 * hashCode + uri.hashCode();
843            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
844            return hashCode;
845        }
846
847        @Override
848        public boolean equals(Object o) {
849            if (o instanceof GrantUri) {
850                GrantUri other = (GrantUri) o;
851                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
852                        && prefix == other.prefix;
853            }
854            return false;
855        }
856
857        @Override
858        public String toString() {
859            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
860            if (prefix) result += " [prefix]";
861            return result;
862        }
863
864        public String toSafeString() {
865            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
866            if (prefix) result += " [prefix]";
867            return result;
868        }
869
870        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
871            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
872                    ContentProvider.getUriWithoutUserId(uri), false);
873        }
874    }
875
876    CoreSettingsObserver mCoreSettingsObserver;
877
878    /**
879     * Thread-local storage used to carry caller permissions over through
880     * indirect content-provider access.
881     */
882    private class Identity {
883        public final IBinder token;
884        public final int pid;
885        public final int uid;
886
887        Identity(IBinder _token, int _pid, int _uid) {
888            token = _token;
889            pid = _pid;
890            uid = _uid;
891        }
892    }
893
894    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
895
896    /**
897     * All information we have collected about the runtime performance of
898     * any user id that can impact battery performance.
899     */
900    final BatteryStatsService mBatteryStatsService;
901
902    /**
903     * Information about component usage
904     */
905    UsageStatsManagerInternal mUsageStatsService;
906
907    /**
908     * Information about and control over application operations
909     */
910    final AppOpsService mAppOpsService;
911
912    /**
913     * Save recent tasks information across reboots.
914     */
915    final TaskPersister mTaskPersister;
916
917    /**
918     * Current configuration information.  HistoryRecord objects are given
919     * a reference to this object to indicate which configuration they are
920     * currently running in, so this object must be kept immutable.
921     */
922    Configuration mConfiguration = new Configuration();
923
924    /**
925     * Current sequencing integer of the configuration, for skipping old
926     * configurations.
927     */
928    int mConfigurationSeq = 0;
929
930    /**
931     * Hardware-reported OpenGLES version.
932     */
933    final int GL_ES_VERSION;
934
935    /**
936     * List of initialization arguments to pass to all processes when binding applications to them.
937     * For example, references to the commonly used services.
938     */
939    HashMap<String, IBinder> mAppBindArgs;
940
941    /**
942     * Temporary to avoid allocations.  Protected by main lock.
943     */
944    final StringBuilder mStringBuilder = new StringBuilder(256);
945
946    /**
947     * Used to control how we initialize the service.
948     */
949    ComponentName mTopComponent;
950    String mTopAction = Intent.ACTION_MAIN;
951    String mTopData;
952    boolean mProcessesReady = false;
953    boolean mSystemReady = false;
954    boolean mBooting = false;
955    boolean mCallFinishBooting = false;
956    boolean mBootAnimationComplete = false;
957    boolean mWaitingUpdate = false;
958    boolean mDidUpdate = false;
959    boolean mOnBattery = false;
960    boolean mLaunchWarningShown = false;
961
962    Context mContext;
963
964    int mFactoryTest;
965
966    boolean mCheckedForSetup;
967
968    /**
969     * The time at which we will allow normal application switches again,
970     * after a call to {@link #stopAppSwitches()}.
971     */
972    long mAppSwitchesAllowedTime;
973
974    /**
975     * This is set to true after the first switch after mAppSwitchesAllowedTime
976     * is set; any switches after that will clear the time.
977     */
978    boolean mDidAppSwitch;
979
980    /**
981     * Last time (in realtime) at which we checked for power usage.
982     */
983    long mLastPowerCheckRealtime;
984
985    /**
986     * Last time (in uptime) at which we checked for power usage.
987     */
988    long mLastPowerCheckUptime;
989
990    /**
991     * Set while we are wanting to sleep, to prevent any
992     * activities from being started/resumed.
993     */
994    private boolean mSleeping = false;
995
996    /**
997     * Set while we are running a voice interaction.  This overrides
998     * sleeping while it is active.
999     */
1000    private boolean mRunningVoice = false;
1001
1002    /**
1003     * State of external calls telling us if the device is awake or asleep.
1004     */
1005    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1006
1007    static final int LOCK_SCREEN_HIDDEN = 0;
1008    static final int LOCK_SCREEN_LEAVING = 1;
1009    static final int LOCK_SCREEN_SHOWN = 2;
1010    /**
1011     * State of external call telling us if the lock screen is shown.
1012     */
1013    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1014
1015    /**
1016     * Set if we are shutting down the system, similar to sleeping.
1017     */
1018    boolean mShuttingDown = false;
1019
1020    /**
1021     * Current sequence id for oom_adj computation traversal.
1022     */
1023    int mAdjSeq = 0;
1024
1025    /**
1026     * Current sequence id for process LRU updating.
1027     */
1028    int mLruSeq = 0;
1029
1030    /**
1031     * Keep track of the non-cached/empty process we last found, to help
1032     * determine how to distribute cached/empty processes next time.
1033     */
1034    int mNumNonCachedProcs = 0;
1035
1036    /**
1037     * Keep track of the number of cached hidden procs, to balance oom adj
1038     * distribution between those and empty procs.
1039     */
1040    int mNumCachedHiddenProcs = 0;
1041
1042    /**
1043     * Keep track of the number of service processes we last found, to
1044     * determine on the next iteration which should be B services.
1045     */
1046    int mNumServiceProcs = 0;
1047    int mNewNumAServiceProcs = 0;
1048    int mNewNumServiceProcs = 0;
1049
1050    /**
1051     * Allow the current computed overall memory level of the system to go down?
1052     * This is set to false when we are killing processes for reasons other than
1053     * memory management, so that the now smaller process list will not be taken as
1054     * an indication that memory is tighter.
1055     */
1056    boolean mAllowLowerMemLevel = false;
1057
1058    /**
1059     * The last computed memory level, for holding when we are in a state that
1060     * processes are going away for other reasons.
1061     */
1062    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1063
1064    /**
1065     * The last total number of process we have, to determine if changes actually look
1066     * like a shrinking number of process due to lower RAM.
1067     */
1068    int mLastNumProcesses;
1069
1070    /**
1071     * The uptime of the last time we performed idle maintenance.
1072     */
1073    long mLastIdleTime = SystemClock.uptimeMillis();
1074
1075    /**
1076     * Total time spent with RAM that has been added in the past since the last idle time.
1077     */
1078    long mLowRamTimeSinceLastIdle = 0;
1079
1080    /**
1081     * If RAM is currently low, when that horrible situation started.
1082     */
1083    long mLowRamStartTime = 0;
1084
1085    /**
1086     * For reporting to battery stats the current top application.
1087     */
1088    private String mCurResumedPackage = null;
1089    private int mCurResumedUid = -1;
1090
1091    /**
1092     * For reporting to battery stats the apps currently running foreground
1093     * service.  The ProcessMap is package/uid tuples; each of these contain
1094     * an array of the currently foreground processes.
1095     */
1096    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1097            = new ProcessMap<ArrayList<ProcessRecord>>();
1098
1099    /**
1100     * This is set if we had to do a delayed dexopt of an app before launching
1101     * it, to increase the ANR timeouts in that case.
1102     */
1103    boolean mDidDexOpt;
1104
1105    /**
1106     * Set if the systemServer made a call to enterSafeMode.
1107     */
1108    boolean mSafeMode;
1109
1110    /**
1111     * If true, we are running under a test environment so will sample PSS from processes
1112     * much more rapidly to try to collect better data when the tests are rapidly
1113     * running through apps.
1114     */
1115    boolean mTestPssMode = false;
1116
1117    String mDebugApp = null;
1118    boolean mWaitForDebugger = false;
1119    boolean mDebugTransient = false;
1120    String mOrigDebugApp = null;
1121    boolean mOrigWaitForDebugger = false;
1122    boolean mAlwaysFinishActivities = false;
1123    IActivityController mController = null;
1124    String mProfileApp = null;
1125    ProcessRecord mProfileProc = null;
1126    String mProfileFile;
1127    ParcelFileDescriptor mProfileFd;
1128    int mSamplingInterval = 0;
1129    boolean mAutoStopProfiler = false;
1130    int mProfileType = 0;
1131    String mOpenGlTraceApp = null;
1132
1133    final long[] mTmpLong = new long[1];
1134
1135    static class ProcessChangeItem {
1136        static final int CHANGE_ACTIVITIES = 1<<0;
1137        static final int CHANGE_PROCESS_STATE = 1<<1;
1138        int changes;
1139        int uid;
1140        int pid;
1141        int processState;
1142        boolean foregroundActivities;
1143    }
1144
1145    final RemoteCallbackList<IProcessObserver> mProcessObservers
1146            = new RemoteCallbackList<IProcessObserver>();
1147    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1148
1149    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1150            = new ArrayList<ProcessChangeItem>();
1151    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1152            = new ArrayList<ProcessChangeItem>();
1153
1154    /**
1155     * Runtime CPU use collection thread.  This object's lock is used to
1156     * perform synchronization with the thread (notifying it to run).
1157     */
1158    final Thread mProcessCpuThread;
1159
1160    /**
1161     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1162     * Must acquire this object's lock when accessing it.
1163     * NOTE: this lock will be held while doing long operations (trawling
1164     * through all processes in /proc), so it should never be acquired by
1165     * any critical paths such as when holding the main activity manager lock.
1166     */
1167    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1168            MONITOR_THREAD_CPU_USAGE);
1169    final AtomicLong mLastCpuTime = new AtomicLong(0);
1170    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1171
1172    long mLastWriteTime = 0;
1173
1174    /**
1175     * Used to retain an update lock when the foreground activity is in
1176     * immersive mode.
1177     */
1178    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1179
1180    /**
1181     * Set to true after the system has finished booting.
1182     */
1183    boolean mBooted = false;
1184
1185    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1186    int mProcessLimitOverride = -1;
1187
1188    WindowManagerService mWindowManager;
1189
1190    final ActivityThread mSystemThread;
1191
1192    // Holds the current foreground user's id
1193    int mCurrentUserId = 0;
1194    // Holds the target user's id during a user switch
1195    int mTargetUserId = UserHandle.USER_NULL;
1196    // If there are multiple profiles for the current user, their ids are here
1197    // Currently only the primary user can have managed profiles
1198    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1199
1200    /**
1201     * Mapping from each known user ID to the profile group ID it is associated with.
1202     */
1203    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1204
1205    private UserManagerService mUserManager;
1206
1207    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1208        final ProcessRecord mApp;
1209        final int mPid;
1210        final IApplicationThread mAppThread;
1211
1212        AppDeathRecipient(ProcessRecord app, int pid,
1213                IApplicationThread thread) {
1214            if (localLOGV) Slog.v(
1215                TAG, "New death recipient " + this
1216                + " for thread " + thread.asBinder());
1217            mApp = app;
1218            mPid = pid;
1219            mAppThread = thread;
1220        }
1221
1222        @Override
1223        public void binderDied() {
1224            if (localLOGV) Slog.v(
1225                TAG, "Death received in " + this
1226                + " for thread " + mAppThread.asBinder());
1227            synchronized(ActivityManagerService.this) {
1228                appDiedLocked(mApp, mPid, mAppThread);
1229            }
1230        }
1231    }
1232
1233    static final int SHOW_ERROR_MSG = 1;
1234    static final int SHOW_NOT_RESPONDING_MSG = 2;
1235    static final int SHOW_FACTORY_ERROR_MSG = 3;
1236    static final int UPDATE_CONFIGURATION_MSG = 4;
1237    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1238    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1239    static final int SERVICE_TIMEOUT_MSG = 12;
1240    static final int UPDATE_TIME_ZONE = 13;
1241    static final int SHOW_UID_ERROR_MSG = 14;
1242    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1243    static final int PROC_START_TIMEOUT_MSG = 20;
1244    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1245    static final int KILL_APPLICATION_MSG = 22;
1246    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1247    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1248    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1249    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1250    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1251    static final int CLEAR_DNS_CACHE_MSG = 28;
1252    static final int UPDATE_HTTP_PROXY_MSG = 29;
1253    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1254    static final int DISPATCH_PROCESSES_CHANGED = 31;
1255    static final int DISPATCH_PROCESS_DIED = 32;
1256    static final int REPORT_MEM_USAGE_MSG = 33;
1257    static final int REPORT_USER_SWITCH_MSG = 34;
1258    static final int CONTINUE_USER_SWITCH_MSG = 35;
1259    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1260    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1261    static final int PERSIST_URI_GRANTS_MSG = 38;
1262    static final int REQUEST_ALL_PSS_MSG = 39;
1263    static final int START_PROFILES_MSG = 40;
1264    static final int UPDATE_TIME = 41;
1265    static final int SYSTEM_USER_START_MSG = 42;
1266    static final int SYSTEM_USER_CURRENT_MSG = 43;
1267    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1268    static final int FINISH_BOOTING_MSG = 45;
1269    static final int START_USER_SWITCH_MSG = 46;
1270    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1271    static final int DISMISS_DIALOG_MSG = 48;
1272    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1273
1274    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1275    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1276    static final int FIRST_COMPAT_MODE_MSG = 300;
1277    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1278
1279    CompatModeDialog mCompatModeDialog;
1280    long mLastMemUsageReportTime = 0;
1281
1282    /**
1283     * Flag whether the current user is a "monkey", i.e. whether
1284     * the UI is driven by a UI automation tool.
1285     */
1286    private boolean mUserIsMonkey;
1287
1288    /** Flag whether the device has a Recents UI */
1289    boolean mHasRecents;
1290
1291    /** The dimensions of the thumbnails in the Recents UI. */
1292    int mThumbnailWidth;
1293    int mThumbnailHeight;
1294
1295    final ServiceThread mHandlerThread;
1296    final MainHandler mHandler;
1297
1298    final class MainHandler extends Handler {
1299        public MainHandler(Looper looper) {
1300            super(looper, null, true);
1301        }
1302
1303        @Override
1304        public void handleMessage(Message msg) {
1305            switch (msg.what) {
1306            case SHOW_ERROR_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1309                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1310                synchronized (ActivityManagerService.this) {
1311                    ProcessRecord proc = (ProcessRecord)data.get("app");
1312                    AppErrorResult res = (AppErrorResult) data.get("result");
1313                    if (proc != null && proc.crashDialog != null) {
1314                        Slog.e(TAG, "App already has crash dialog: " + proc);
1315                        if (res != null) {
1316                            res.set(0);
1317                        }
1318                        return;
1319                    }
1320                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1321                            >= Process.FIRST_APPLICATION_UID
1322                            && proc.pid != MY_PID);
1323                    for (int userId : mCurrentProfileIds) {
1324                        isBackground &= (proc.userId != userId);
1325                    }
1326                    if (isBackground && !showBackground) {
1327                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1328                        if (res != null) {
1329                            res.set(0);
1330                        }
1331                        return;
1332                    }
1333                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1334                        Dialog d = new AppErrorDialog(mContext,
1335                                ActivityManagerService.this, res, proc);
1336                        d.show();
1337                        proc.crashDialog = d;
1338                    } else {
1339                        // The device is asleep, so just pretend that the user
1340                        // saw a crash dialog and hit "force quit".
1341                        if (res != null) {
1342                            res.set(0);
1343                        }
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_NOT_RESPONDING_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1352                    ProcessRecord proc = (ProcessRecord)data.get("app");
1353                    if (proc != null && proc.anrDialog != null) {
1354                        Slog.e(TAG, "App already has anr dialog: " + proc);
1355                        return;
1356                    }
1357
1358                    Intent intent = new Intent("android.intent.action.ANR");
1359                    if (!mProcessesReady) {
1360                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1361                                | Intent.FLAG_RECEIVER_FOREGROUND);
1362                    }
1363                    broadcastIntentLocked(null, null, intent,
1364                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1365                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1366
1367                    if (mShowDialogs) {
1368                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1369                                mContext, proc, (ActivityRecord)data.get("activity"),
1370                                msg.arg1 != 0);
1371                        d.show();
1372                        proc.anrDialog = d;
1373                    } else {
1374                        // Just kill the app if there is no dialog to be shown.
1375                        killAppAtUsersRequest(proc, null);
1376                    }
1377                }
1378
1379                ensureBootCompleted();
1380            } break;
1381            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1382                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1383                synchronized (ActivityManagerService.this) {
1384                    ProcessRecord proc = (ProcessRecord) data.get("app");
1385                    if (proc == null) {
1386                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1387                        break;
1388                    }
1389                    if (proc.crashDialog != null) {
1390                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1391                        return;
1392                    }
1393                    AppErrorResult res = (AppErrorResult) data.get("result");
1394                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1395                        Dialog d = new StrictModeViolationDialog(mContext,
1396                                ActivityManagerService.this, res, proc);
1397                        d.show();
1398                        proc.crashDialog = d;
1399                    } else {
1400                        // The device is asleep, so just pretend that the user
1401                        // saw a crash dialog and hit "force quit".
1402                        res.set(0);
1403                    }
1404                }
1405                ensureBootCompleted();
1406            } break;
1407            case SHOW_FACTORY_ERROR_MSG: {
1408                Dialog d = new FactoryErrorDialog(
1409                    mContext, msg.getData().getCharSequence("msg"));
1410                d.show();
1411                ensureBootCompleted();
1412            } break;
1413            case UPDATE_CONFIGURATION_MSG: {
1414                final ContentResolver resolver = mContext.getContentResolver();
1415                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1416            } break;
1417            case GC_BACKGROUND_PROCESSES_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    performAppGcsIfAppropriateLocked();
1420                }
1421            } break;
1422            case WAIT_FOR_DEBUGGER_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    ProcessRecord app = (ProcessRecord)msg.obj;
1425                    if (msg.arg1 != 0) {
1426                        if (!app.waitedForDebugger) {
1427                            Dialog d = new AppWaitingForDebuggerDialog(
1428                                    ActivityManagerService.this,
1429                                    mContext, app);
1430                            app.waitDialog = d;
1431                            app.waitedForDebugger = true;
1432                            d.show();
1433                        }
1434                    } else {
1435                        if (app.waitDialog != null) {
1436                            app.waitDialog.dismiss();
1437                            app.waitDialog = null;
1438                        }
1439                    }
1440                }
1441            } break;
1442            case SERVICE_TIMEOUT_MSG: {
1443                if (mDidDexOpt) {
1444                    mDidDexOpt = false;
1445                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1446                    nmsg.obj = msg.obj;
1447                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1448                    return;
1449                }
1450                mServices.serviceTimeout((ProcessRecord)msg.obj);
1451            } break;
1452            case UPDATE_TIME_ZONE: {
1453                synchronized (ActivityManagerService.this) {
1454                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1455                        ProcessRecord r = mLruProcesses.get(i);
1456                        if (r.thread != null) {
1457                            try {
1458                                r.thread.updateTimeZone();
1459                            } catch (RemoteException ex) {
1460                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1461                            }
1462                        }
1463                    }
1464                }
1465            } break;
1466            case CLEAR_DNS_CACHE_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1469                        ProcessRecord r = mLruProcesses.get(i);
1470                        if (r.thread != null) {
1471                            try {
1472                                r.thread.clearDnsCache();
1473                            } catch (RemoteException ex) {
1474                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1475                            }
1476                        }
1477                    }
1478                }
1479            } break;
1480            case UPDATE_HTTP_PROXY_MSG: {
1481                ProxyInfo proxy = (ProxyInfo)msg.obj;
1482                String host = "";
1483                String port = "";
1484                String exclList = "";
1485                Uri pacFileUrl = Uri.EMPTY;
1486                if (proxy != null) {
1487                    host = proxy.getHost();
1488                    port = Integer.toString(proxy.getPort());
1489                    exclList = proxy.getExclusionListAsString();
1490                    pacFileUrl = proxy.getPacFileUrl();
1491                }
1492                synchronized (ActivityManagerService.this) {
1493                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1494                        ProcessRecord r = mLruProcesses.get(i);
1495                        if (r.thread != null) {
1496                            try {
1497                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1498                            } catch (RemoteException ex) {
1499                                Slog.w(TAG, "Failed to update http proxy for: " +
1500                                        r.info.processName);
1501                            }
1502                        }
1503                    }
1504                }
1505            } break;
1506            case SHOW_UID_ERROR_MSG: {
1507                if (mShowDialogs) {
1508                    AlertDialog d = new BaseErrorDialog(mContext);
1509                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1510                    d.setCancelable(false);
1511                    d.setTitle(mContext.getText(R.string.android_system_label));
1512                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1513                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1514                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1515                    d.show();
1516                }
1517            } break;
1518            case SHOW_FINGERPRINT_ERROR_MSG: {
1519                if (mShowDialogs) {
1520                    AlertDialog d = new BaseErrorDialog(mContext);
1521                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1522                    d.setCancelable(false);
1523                    d.setTitle(mContext.getText(R.string.android_system_label));
1524                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1525                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1526                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1527                    d.show();
1528                }
1529            } break;
1530            case PROC_START_TIMEOUT_MSG: {
1531                if (mDidDexOpt) {
1532                    mDidDexOpt = false;
1533                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1534                    nmsg.obj = msg.obj;
1535                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1536                    return;
1537                }
1538                ProcessRecord app = (ProcessRecord)msg.obj;
1539                synchronized (ActivityManagerService.this) {
1540                    processStartTimedOutLocked(app);
1541                }
1542            } break;
1543            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1546                }
1547            } break;
1548            case KILL_APPLICATION_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    int appid = msg.arg1;
1551                    boolean restart = (msg.arg2 == 1);
1552                    Bundle bundle = (Bundle)msg.obj;
1553                    String pkg = bundle.getString("pkg");
1554                    String reason = bundle.getString("reason");
1555                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1556                            false, UserHandle.USER_ALL, reason);
1557                }
1558            } break;
1559            case FINALIZE_PENDING_INTENT_MSG: {
1560                ((PendingIntentRecord)msg.obj).completeFinalize();
1561            } break;
1562            case POST_HEAVY_NOTIFICATION_MSG: {
1563                INotificationManager inm = NotificationManager.getService();
1564                if (inm == null) {
1565                    return;
1566                }
1567
1568                ActivityRecord root = (ActivityRecord)msg.obj;
1569                ProcessRecord process = root.app;
1570                if (process == null) {
1571                    return;
1572                }
1573
1574                try {
1575                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1576                    String text = mContext.getString(R.string.heavy_weight_notification,
1577                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1578                    Notification notification = new Notification();
1579                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1580                    notification.when = 0;
1581                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1582                    notification.tickerText = text;
1583                    notification.defaults = 0; // please be quiet
1584                    notification.sound = null;
1585                    notification.vibrate = null;
1586                    notification.color = mContext.getResources().getColor(
1587                            com.android.internal.R.color.system_notification_accent_color);
1588                    notification.setLatestEventInfo(context, text,
1589                            mContext.getText(R.string.heavy_weight_notification_detail),
1590                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1591                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1592                                    new UserHandle(root.userId)));
1593
1594                    try {
1595                        int[] outId = new int[1];
1596                        inm.enqueueNotificationWithTag("android", "android", null,
1597                                R.string.heavy_weight_notification,
1598                                notification, outId, root.userId);
1599                    } catch (RuntimeException e) {
1600                        Slog.w(ActivityManagerService.TAG,
1601                                "Error showing notification for heavy-weight app", e);
1602                    } catch (RemoteException e) {
1603                    }
1604                } catch (NameNotFoundException e) {
1605                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1606                }
1607            } break;
1608            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1609                INotificationManager inm = NotificationManager.getService();
1610                if (inm == null) {
1611                    return;
1612                }
1613                try {
1614                    inm.cancelNotificationWithTag("android", null,
1615                            R.string.heavy_weight_notification,  msg.arg1);
1616                } catch (RuntimeException e) {
1617                    Slog.w(ActivityManagerService.TAG,
1618                            "Error canceling notification for service", e);
1619                } catch (RemoteException e) {
1620                }
1621            } break;
1622            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    checkExcessivePowerUsageLocked(true);
1625                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1626                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1627                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1628                }
1629            } break;
1630            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1631                synchronized (ActivityManagerService.this) {
1632                    ActivityRecord ar = (ActivityRecord)msg.obj;
1633                    if (mCompatModeDialog != null) {
1634                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1635                                ar.info.applicationInfo.packageName)) {
1636                            return;
1637                        }
1638                        mCompatModeDialog.dismiss();
1639                        mCompatModeDialog = null;
1640                    }
1641                    if (ar != null && false) {
1642                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1643                                ar.packageName)) {
1644                            int mode = mCompatModePackages.computeCompatModeLocked(
1645                                    ar.info.applicationInfo);
1646                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1647                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1648                                mCompatModeDialog = new CompatModeDialog(
1649                                        ActivityManagerService.this, mContext,
1650                                        ar.info.applicationInfo);
1651                                mCompatModeDialog.show();
1652                            }
1653                        }
1654                    }
1655                }
1656                break;
1657            }
1658            case DISPATCH_PROCESSES_CHANGED: {
1659                dispatchProcessesChanged();
1660                break;
1661            }
1662            case DISPATCH_PROCESS_DIED: {
1663                final int pid = msg.arg1;
1664                final int uid = msg.arg2;
1665                dispatchProcessDied(pid, uid);
1666                break;
1667            }
1668            case REPORT_MEM_USAGE_MSG: {
1669                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1670                Thread thread = new Thread() {
1671                    @Override public void run() {
1672                        reportMemUsage(memInfos);
1673                    }
1674                };
1675                thread.start();
1676                break;
1677            }
1678            case START_USER_SWITCH_MSG: {
1679                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1680                break;
1681            }
1682            case REPORT_USER_SWITCH_MSG: {
1683                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1684                break;
1685            }
1686            case CONTINUE_USER_SWITCH_MSG: {
1687                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1688                break;
1689            }
1690            case USER_SWITCH_TIMEOUT_MSG: {
1691                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1692                break;
1693            }
1694            case IMMERSIVE_MODE_LOCK_MSG: {
1695                final boolean nextState = (msg.arg1 != 0);
1696                if (mUpdateLock.isHeld() != nextState) {
1697                    if (DEBUG_IMMERSIVE) {
1698                        final ActivityRecord r = (ActivityRecord) msg.obj;
1699                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1700                    }
1701                    if (nextState) {
1702                        mUpdateLock.acquire();
1703                    } else {
1704                        mUpdateLock.release();
1705                    }
1706                }
1707                break;
1708            }
1709            case PERSIST_URI_GRANTS_MSG: {
1710                writeGrantedUriPermissions();
1711                break;
1712            }
1713            case REQUEST_ALL_PSS_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1716                }
1717                break;
1718            }
1719            case START_PROFILES_MSG: {
1720                synchronized (ActivityManagerService.this) {
1721                    startProfilesLocked();
1722                }
1723                break;
1724            }
1725            case UPDATE_TIME: {
1726                synchronized (ActivityManagerService.this) {
1727                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1728                        ProcessRecord r = mLruProcesses.get(i);
1729                        if (r.thread != null) {
1730                            try {
1731                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1732                            } catch (RemoteException ex) {
1733                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1734                            }
1735                        }
1736                    }
1737                }
1738                break;
1739            }
1740            case SYSTEM_USER_START_MSG: {
1741                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1742                        Integer.toString(msg.arg1), msg.arg1);
1743                mSystemServiceManager.startUser(msg.arg1);
1744                break;
1745            }
1746            case SYSTEM_USER_CURRENT_MSG: {
1747                mBatteryStatsService.noteEvent(
1748                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1749                        Integer.toString(msg.arg2), msg.arg2);
1750                mBatteryStatsService.noteEvent(
1751                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1752                        Integer.toString(msg.arg1), msg.arg1);
1753                mSystemServiceManager.switchUser(msg.arg1);
1754                break;
1755            }
1756            case ENTER_ANIMATION_COMPLETE_MSG: {
1757                synchronized (ActivityManagerService.this) {
1758                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1759                    if (r != null && r.app != null && r.app.thread != null) {
1760                        try {
1761                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1762                        } catch (RemoteException e) {
1763                        }
1764                    }
1765                }
1766                break;
1767            }
1768            case FINISH_BOOTING_MSG: {
1769                if (msg.arg1 != 0) {
1770                    finishBooting();
1771                }
1772                if (msg.arg2 != 0) {
1773                    enableScreenAfterBoot();
1774                }
1775                break;
1776            }
1777            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1778                try {
1779                    Locale l = (Locale) msg.obj;
1780                    IBinder service = ServiceManager.getService("mount");
1781                    IMountService mountService = IMountService.Stub.asInterface(service);
1782                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1783                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1784                } catch (RemoteException e) {
1785                    Log.e(TAG, "Error storing locale for decryption UI", e);
1786                }
1787                break;
1788            }
1789            case DISMISS_DIALOG_MSG: {
1790                final Dialog d = (Dialog) msg.obj;
1791                d.dismiss();
1792                break;
1793            }
1794            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1795                synchronized (ActivityManagerService.this) {
1796                    int i = mTaskStackListeners.beginBroadcast();
1797                    while (i > 0) {
1798                        i--;
1799                        try {
1800                            // Make a one-way callback to the listener
1801                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1802                        } catch (RemoteException e){
1803                            // Handled by the RemoteCallbackList
1804                        }
1805                    }
1806                    mTaskStackListeners.finishBroadcast();
1807                }
1808                break;
1809            }
1810            }
1811        }
1812    };
1813
1814    static final int COLLECT_PSS_BG_MSG = 1;
1815
1816    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1817        @Override
1818        public void handleMessage(Message msg) {
1819            switch (msg.what) {
1820            case COLLECT_PSS_BG_MSG: {
1821                long start = SystemClock.uptimeMillis();
1822                MemInfoReader memInfo = null;
1823                synchronized (ActivityManagerService.this) {
1824                    if (mFullPssPending) {
1825                        mFullPssPending = false;
1826                        memInfo = new MemInfoReader();
1827                    }
1828                }
1829                if (memInfo != null) {
1830                    updateCpuStatsNow();
1831                    long nativeTotalPss = 0;
1832                    synchronized (mProcessCpuTracker) {
1833                        final int N = mProcessCpuTracker.countStats();
1834                        for (int j=0; j<N; j++) {
1835                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1836                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (ActivityManagerService.this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1855                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1856                    }
1857                }
1858
1859                int num = 0;
1860                long[] tmp = new long[1];
1861                do {
1862                    ProcessRecord proc;
1863                    int procState;
1864                    int pid;
1865                    long lastPssTime;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (mPendingPssProcesses.size() <= 0) {
1868                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.remove(0);
1874                        procState = proc.pssProcState;
1875                        lastPssTime = proc.lastPssTime;
1876                        if (proc.thread != null && procState == proc.setProcState
1877                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1878                                        < SystemClock.uptimeMillis()) {
1879                            pid = proc.pid;
1880                        } else {
1881                            proc = null;
1882                            pid = 0;
1883                        }
1884                    }
1885                    if (proc != null) {
1886                        long pss = Debug.getPss(pid, tmp, null);
1887                        synchronized (ActivityManagerService.this) {
1888                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1889                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1890                                num++;
1891                                recordPssSample(proc, procState, pss, tmp[0],
1892                                        SystemClock.uptimeMillis());
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    public void setSystemProcess() {
1903        try {
1904            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1905            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1906            ServiceManager.addService("meminfo", new MemBinder(this));
1907            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1908            ServiceManager.addService("dbinfo", new DbBinder(this));
1909            if (MONITOR_CPU_USAGE) {
1910                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1911            }
1912            ServiceManager.addService("permission", new PermissionController(this));
1913
1914            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1915                    "android", STOCK_PM_FLAGS);
1916            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1917
1918            synchronized (this) {
1919                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1920                app.persistent = true;
1921                app.pid = MY_PID;
1922                app.maxAdj = ProcessList.SYSTEM_ADJ;
1923                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1924                mProcessNames.put(app.processName, app.uid, app);
1925                synchronized (mPidsSelfLocked) {
1926                    mPidsSelfLocked.put(app.pid, app);
1927                }
1928                updateLruProcessLocked(app, false, null);
1929                updateOomAdjLocked();
1930            }
1931        } catch (PackageManager.NameNotFoundException e) {
1932            throw new RuntimeException(
1933                    "Unable to find android system package", e);
1934        }
1935    }
1936
1937    public void setWindowManager(WindowManagerService wm) {
1938        mWindowManager = wm;
1939        mStackSupervisor.setWindowManager(wm);
1940    }
1941
1942    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1943        mUsageStatsService = usageStatsManager;
1944    }
1945
1946    public void startObservingNativeCrashes() {
1947        final NativeCrashListener ncl = new NativeCrashListener(this);
1948        ncl.start();
1949    }
1950
1951    public IAppOpsService getAppOpsService() {
1952        return mAppOpsService;
1953    }
1954
1955    static class MemBinder extends Binder {
1956        ActivityManagerService mActivityManagerService;
1957        MemBinder(ActivityManagerService activityManagerService) {
1958            mActivityManagerService = activityManagerService;
1959        }
1960
1961        @Override
1962        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1963            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1964                    != PackageManager.PERMISSION_GRANTED) {
1965                pw.println("Permission Denial: can't dump meminfo from from pid="
1966                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1967                        + " without permission " + android.Manifest.permission.DUMP);
1968                return;
1969            }
1970
1971            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1972        }
1973    }
1974
1975    static class GraphicsBinder extends Binder {
1976        ActivityManagerService mActivityManagerService;
1977        GraphicsBinder(ActivityManagerService activityManagerService) {
1978            mActivityManagerService = activityManagerService;
1979        }
1980
1981        @Override
1982        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1983            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1984                    != PackageManager.PERMISSION_GRANTED) {
1985                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1986                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1987                        + " without permission " + android.Manifest.permission.DUMP);
1988                return;
1989            }
1990
1991            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1992        }
1993    }
1994
1995    static class DbBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        DbBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump dbinfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpDbInfo(fd, pw, args);
2012        }
2013    }
2014
2015    static class CpuBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        CpuBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            synchronized (mActivityManagerService.mProcessCpuTracker) {
2032                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2033                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2034                        SystemClock.uptimeMillis()));
2035            }
2036        }
2037    }
2038
2039    public static final class Lifecycle extends SystemService {
2040        private final ActivityManagerService mService;
2041
2042        public Lifecycle(Context context) {
2043            super(context);
2044            mService = new ActivityManagerService(context);
2045        }
2046
2047        @Override
2048        public void onStart() {
2049            mService.start();
2050        }
2051
2052        public ActivityManagerService getService() {
2053            return mService;
2054        }
2055    }
2056
2057    // Note: This method is invoked on the main thread but may need to attach various
2058    // handlers to other threads.  So take care to be explicit about the looper.
2059    public ActivityManagerService(Context systemContext) {
2060        mContext = systemContext;
2061        mFactoryTest = FactoryTest.getMode();
2062        mSystemThread = ActivityThread.currentActivityThread();
2063
2064        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2065
2066        mHandlerThread = new ServiceThread(TAG,
2067                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2068        mHandlerThread.start();
2069        mHandler = new MainHandler(mHandlerThread.getLooper());
2070
2071        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2072                "foreground", BROADCAST_FG_TIMEOUT, false);
2073        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2074                "background", BROADCAST_BG_TIMEOUT, true);
2075        mBroadcastQueues[0] = mFgBroadcastQueue;
2076        mBroadcastQueues[1] = mBgBroadcastQueue;
2077
2078        mServices = new ActiveServices(this);
2079        mProviderMap = new ProviderMap(this);
2080
2081        // TODO: Move creation of battery stats service outside of activity manager service.
2082        File dataDir = Environment.getDataDirectory();
2083        File systemDir = new File(dataDir, "system");
2084        systemDir.mkdirs();
2085        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2086        mBatteryStatsService.getActiveStatistics().readLocked();
2087        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2088        mOnBattery = DEBUG_POWER ? true
2089                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2090        mBatteryStatsService.getActiveStatistics().setCallback(this);
2091
2092        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2093
2094        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2095
2096        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2097
2098        // User 0 is the first and only user that runs at boot.
2099        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2100        mUserLru.add(Integer.valueOf(0));
2101        updateStartedUserArrayLocked();
2102
2103        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2104            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2105
2106        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2107
2108        mConfiguration.setToDefaults();
2109        mConfiguration.locale = Locale.getDefault();
2110
2111        mConfigurationSeq = mConfiguration.seq = 1;
2112        mProcessCpuTracker.init();
2113
2114        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2115        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2116        mStackSupervisor = new ActivityStackSupervisor(this);
2117        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2118
2119        mProcessCpuThread = new Thread("CpuTracker") {
2120            @Override
2121            public void run() {
2122                while (true) {
2123                    try {
2124                        try {
2125                            synchronized(this) {
2126                                final long now = SystemClock.uptimeMillis();
2127                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2128                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2129                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2130                                //        + ", write delay=" + nextWriteDelay);
2131                                if (nextWriteDelay < nextCpuDelay) {
2132                                    nextCpuDelay = nextWriteDelay;
2133                                }
2134                                if (nextCpuDelay > 0) {
2135                                    mProcessCpuMutexFree.set(true);
2136                                    this.wait(nextCpuDelay);
2137                                }
2138                            }
2139                        } catch (InterruptedException e) {
2140                        }
2141                        updateCpuStatsNow();
2142                    } catch (Exception e) {
2143                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2144                    }
2145                }
2146            }
2147        };
2148
2149        Watchdog.getInstance().addMonitor(this);
2150        Watchdog.getInstance().addThread(mHandler);
2151    }
2152
2153    public void setSystemServiceManager(SystemServiceManager mgr) {
2154        mSystemServiceManager = mgr;
2155    }
2156
2157    public void setInstaller(Installer installer) {
2158        mInstaller = installer;
2159    }
2160
2161    private void start() {
2162        Process.removeAllProcessGroups();
2163        mProcessCpuThread.start();
2164
2165        mBatteryStatsService.publish(mContext);
2166        mAppOpsService.publish(mContext);
2167        Slog.d("AppOps", "AppOpsService published");
2168        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2169    }
2170
2171    public void initPowerManagement() {
2172        mStackSupervisor.initPowerManagement();
2173        mBatteryStatsService.initPowerManagement();
2174    }
2175
2176    @Override
2177    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2178            throws RemoteException {
2179        if (code == SYSPROPS_TRANSACTION) {
2180            // We need to tell all apps about the system property change.
2181            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2182            synchronized(this) {
2183                final int NP = mProcessNames.getMap().size();
2184                for (int ip=0; ip<NP; ip++) {
2185                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2186                    final int NA = apps.size();
2187                    for (int ia=0; ia<NA; ia++) {
2188                        ProcessRecord app = apps.valueAt(ia);
2189                        if (app.thread != null) {
2190                            procs.add(app.thread.asBinder());
2191                        }
2192                    }
2193                }
2194            }
2195
2196            int N = procs.size();
2197            for (int i=0; i<N; i++) {
2198                Parcel data2 = Parcel.obtain();
2199                try {
2200                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2201                } catch (RemoteException e) {
2202                }
2203                data2.recycle();
2204            }
2205        }
2206        try {
2207            return super.onTransact(code, data, reply, flags);
2208        } catch (RuntimeException e) {
2209            // The activity manager only throws security exceptions, so let's
2210            // log all others.
2211            if (!(e instanceof SecurityException)) {
2212                Slog.wtf(TAG, "Activity Manager Crash", e);
2213            }
2214            throw e;
2215        }
2216    }
2217
2218    void updateCpuStats() {
2219        final long now = SystemClock.uptimeMillis();
2220        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2221            return;
2222        }
2223        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2224            synchronized (mProcessCpuThread) {
2225                mProcessCpuThread.notify();
2226            }
2227        }
2228    }
2229
2230    void updateCpuStatsNow() {
2231        synchronized (mProcessCpuTracker) {
2232            mProcessCpuMutexFree.set(false);
2233            final long now = SystemClock.uptimeMillis();
2234            boolean haveNewCpuStats = false;
2235
2236            if (MONITOR_CPU_USAGE &&
2237                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2238                mLastCpuTime.set(now);
2239                haveNewCpuStats = true;
2240                mProcessCpuTracker.update();
2241                //Slog.i(TAG, mProcessCpu.printCurrentState());
2242                //Slog.i(TAG, "Total CPU usage: "
2243                //        + mProcessCpu.getTotalCpuPercent() + "%");
2244
2245                // Slog the cpu usage if the property is set.
2246                if ("true".equals(SystemProperties.get("events.cpu"))) {
2247                    int user = mProcessCpuTracker.getLastUserTime();
2248                    int system = mProcessCpuTracker.getLastSystemTime();
2249                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2250                    int irq = mProcessCpuTracker.getLastIrqTime();
2251                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2252                    int idle = mProcessCpuTracker.getLastIdleTime();
2253
2254                    int total = user + system + iowait + irq + softIrq + idle;
2255                    if (total == 0) total = 1;
2256
2257                    EventLog.writeEvent(EventLogTags.CPU,
2258                            ((user+system+iowait+irq+softIrq) * 100) / total,
2259                            (user * 100) / total,
2260                            (system * 100) / total,
2261                            (iowait * 100) / total,
2262                            (irq * 100) / total,
2263                            (softIrq * 100) / total);
2264                }
2265            }
2266
2267            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2268            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2269            synchronized(bstats) {
2270                synchronized(mPidsSelfLocked) {
2271                    if (haveNewCpuStats) {
2272                        if (mOnBattery) {
2273                            int perc = bstats.startAddingCpuLocked();
2274                            int totalUTime = 0;
2275                            int totalSTime = 0;
2276                            final int N = mProcessCpuTracker.countStats();
2277                            for (int i=0; i<N; i++) {
2278                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2279                                if (!st.working) {
2280                                    continue;
2281                                }
2282                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2283                                int otherUTime = (st.rel_utime*perc)/100;
2284                                int otherSTime = (st.rel_stime*perc)/100;
2285                                totalUTime += otherUTime;
2286                                totalSTime += otherSTime;
2287                                if (pr != null) {
2288                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2289                                    if (ps == null || !ps.isActive()) {
2290                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2291                                                pr.info.uid, pr.processName);
2292                                    }
2293                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2294                                            st.rel_stime-otherSTime);
2295                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2296                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2297                                } else {
2298                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2299                                    if (ps == null || !ps.isActive()) {
2300                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2301                                                bstats.mapUid(st.uid), st.name);
2302                                    }
2303                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2304                                            st.rel_stime-otherSTime);
2305                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2306                                }
2307                            }
2308                            bstats.finishAddingCpuLocked(perc, totalUTime,
2309                                    totalSTime, cpuSpeedTimes);
2310                        }
2311                    }
2312                }
2313
2314                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2315                    mLastWriteTime = now;
2316                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2317                }
2318            }
2319        }
2320    }
2321
2322    @Override
2323    public void batteryNeedsCpuUpdate() {
2324        updateCpuStatsNow();
2325    }
2326
2327    @Override
2328    public void batteryPowerChanged(boolean onBattery) {
2329        // When plugging in, update the CPU stats first before changing
2330        // the plug state.
2331        updateCpuStatsNow();
2332        synchronized (this) {
2333            synchronized(mPidsSelfLocked) {
2334                mOnBattery = DEBUG_POWER ? true : onBattery;
2335            }
2336        }
2337    }
2338
2339    /**
2340     * Initialize the application bind args. These are passed to each
2341     * process when the bindApplication() IPC is sent to the process. They're
2342     * lazily setup to make sure the services are running when they're asked for.
2343     */
2344    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2345        if (mAppBindArgs == null) {
2346            mAppBindArgs = new HashMap<>();
2347
2348            // Isolated processes won't get this optimization, so that we don't
2349            // violate the rules about which services they have access to.
2350            if (!isolated) {
2351                // Setup the application init args
2352                mAppBindArgs.put("package", ServiceManager.getService("package"));
2353                mAppBindArgs.put("window", ServiceManager.getService("window"));
2354                mAppBindArgs.put(Context.ALARM_SERVICE,
2355                        ServiceManager.getService(Context.ALARM_SERVICE));
2356            }
2357        }
2358        return mAppBindArgs;
2359    }
2360
2361    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
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, reason + " setFocusedActivity");
2371            if (r != null) {
2372                mWindowManager.setFocusedApp(r.appToken, true);
2373            }
2374            applyUpdateLockStateLocked(r);
2375        }
2376        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2377                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2378    }
2379
2380    final void clearFocusedActivity(ActivityRecord r) {
2381        if (mFocusedActivity == r) {
2382            mFocusedActivity = null;
2383        }
2384    }
2385
2386    @Override
2387    public void setFocusedStack(int stackId) {
2388        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2389        synchronized (ActivityManagerService.this) {
2390            ActivityStack stack = mStackSupervisor.getStack(stackId);
2391            if (stack != null) {
2392                ActivityRecord r = stack.topRunningActivityLocked(null);
2393                if (r != null) {
2394                    setFocusedActivityLocked(r, "setFocusedStack");
2395                }
2396            }
2397        }
2398    }
2399
2400    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2401    @Override
2402    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2403        synchronized (ActivityManagerService.this) {
2404            if (listener != null) {
2405                mTaskStackListeners.register(listener);
2406            }
2407        }
2408    }
2409
2410    @Override
2411    public void notifyActivityDrawn(IBinder token) {
2412        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2413        synchronized (this) {
2414            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2415            if (r != null) {
2416                r.task.stack.notifyActivityDrawnLocked(r);
2417            }
2418        }
2419    }
2420
2421    final void applyUpdateLockStateLocked(ActivityRecord r) {
2422        // Modifications to the UpdateLock state are done on our handler, outside
2423        // the activity manager's locks.  The new state is determined based on the
2424        // state *now* of the relevant activity record.  The object is passed to
2425        // the handler solely for logging detail, not to be consulted/modified.
2426        final boolean nextState = r != null && r.immersive;
2427        mHandler.sendMessage(
2428                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2429    }
2430
2431    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2432        Message msg = Message.obtain();
2433        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2434        msg.obj = r.task.askedCompatMode ? null : r;
2435        mHandler.sendMessage(msg);
2436    }
2437
2438    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2439            String what, Object obj, ProcessRecord srcApp) {
2440        app.lastActivityTime = now;
2441
2442        if (app.activities.size() > 0) {
2443            // Don't want to touch dependent processes that are hosting activities.
2444            return index;
2445        }
2446
2447        int lrui = mLruProcesses.lastIndexOf(app);
2448        if (lrui < 0) {
2449            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2450                    + what + " " + obj + " from " + srcApp);
2451            return index;
2452        }
2453
2454        if (lrui >= index) {
2455            // Don't want to cause this to move dependent processes *back* in the
2456            // list as if they were less frequently used.
2457            return index;
2458        }
2459
2460        if (lrui >= mLruProcessActivityStart) {
2461            // Don't want to touch dependent processes that are hosting activities.
2462            return index;
2463        }
2464
2465        mLruProcesses.remove(lrui);
2466        if (index > 0) {
2467            index--;
2468        }
2469        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2470                + " in LRU list: " + app);
2471        mLruProcesses.add(index, app);
2472        return index;
2473    }
2474
2475    final void removeLruProcessLocked(ProcessRecord app) {
2476        int lrui = mLruProcesses.lastIndexOf(app);
2477        if (lrui >= 0) {
2478            if (!app.killed) {
2479                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2480                Process.killProcessQuiet(app.pid);
2481                Process.killProcessGroup(app.info.uid, app.pid);
2482            }
2483            if (lrui <= mLruProcessActivityStart) {
2484                mLruProcessActivityStart--;
2485            }
2486            if (lrui <= mLruProcessServiceStart) {
2487                mLruProcessServiceStart--;
2488            }
2489            mLruProcesses.remove(lrui);
2490        }
2491    }
2492
2493    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2494            ProcessRecord client) {
2495        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2496                || app.treatLikeActivity;
2497        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2498        if (!activityChange && hasActivity) {
2499            // The process has activities, so we are only allowing activity-based adjustments
2500            // to move it.  It should be kept in the front of the list with other
2501            // processes that have activities, and we don't want those to change their
2502            // order except due to activity operations.
2503            return;
2504        }
2505
2506        mLruSeq++;
2507        final long now = SystemClock.uptimeMillis();
2508        app.lastActivityTime = now;
2509
2510        // First a quick reject: if the app is already at the position we will
2511        // put it, then there is nothing to do.
2512        if (hasActivity) {
2513            final int N = mLruProcesses.size();
2514            if (N > 0 && mLruProcesses.get(N-1) == app) {
2515                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2516                return;
2517            }
2518        } else {
2519            if (mLruProcessServiceStart > 0
2520                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2521                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2522                return;
2523            }
2524        }
2525
2526        int lrui = mLruProcesses.lastIndexOf(app);
2527
2528        if (app.persistent && lrui >= 0) {
2529            // We don't care about the position of persistent processes, as long as
2530            // they are in the list.
2531            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2532            return;
2533        }
2534
2535        /* In progress: compute new position first, so we can avoid doing work
2536           if the process is not actually going to move.  Not yet working.
2537        int addIndex;
2538        int nextIndex;
2539        boolean inActivity = false, inService = false;
2540        if (hasActivity) {
2541            // Process has activities, put it at the very tipsy-top.
2542            addIndex = mLruProcesses.size();
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545        } else if (hasService) {
2546            // Process has services, put it at the top of the service list.
2547            addIndex = mLruProcessActivityStart;
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550            inService = true;
2551        } else  {
2552            // Process not otherwise of interest, it goes to the top of the non-service area.
2553            addIndex = mLruProcessServiceStart;
2554            if (client != null) {
2555                int clientIndex = mLruProcesses.lastIndexOf(client);
2556                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2557                        + app);
2558                if (clientIndex >= 0 && addIndex > clientIndex) {
2559                    addIndex = clientIndex;
2560                }
2561            }
2562            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2563        }
2564
2565        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2566                + mLruProcessActivityStart + "): " + app);
2567        */
2568
2569        if (lrui >= 0) {
2570            if (lrui < mLruProcessActivityStart) {
2571                mLruProcessActivityStart--;
2572            }
2573            if (lrui < mLruProcessServiceStart) {
2574                mLruProcessServiceStart--;
2575            }
2576            /*
2577            if (addIndex > lrui) {
2578                addIndex--;
2579            }
2580            if (nextIndex > lrui) {
2581                nextIndex--;
2582            }
2583            */
2584            mLruProcesses.remove(lrui);
2585        }
2586
2587        /*
2588        mLruProcesses.add(addIndex, app);
2589        if (inActivity) {
2590            mLruProcessActivityStart++;
2591        }
2592        if (inService) {
2593            mLruProcessActivityStart++;
2594        }
2595        */
2596
2597        int nextIndex;
2598        if (hasActivity) {
2599            final int N = mLruProcesses.size();
2600            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2601                // Process doesn't have activities, but has clients with
2602                // activities...  move it up, but one below the top (the top
2603                // should always have a real activity).
2604                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2605                mLruProcesses.add(N-1, app);
2606                // To keep it from spamming the LRU list (by making a bunch of clients),
2607                // we will push down any other entries owned by the app.
2608                final int uid = app.info.uid;
2609                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2610                    ProcessRecord subProc = mLruProcesses.get(i);
2611                    if (subProc.info.uid == uid) {
2612                        // We want to push this one down the list.  If the process after
2613                        // it is for the same uid, however, don't do so, because we don't
2614                        // want them internally to be re-ordered.
2615                        if (mLruProcesses.get(i-1).info.uid != uid) {
2616                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2617                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2618                            ProcessRecord tmp = mLruProcesses.get(i);
2619                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2620                            mLruProcesses.set(i-1, tmp);
2621                            i--;
2622                        }
2623                    } else {
2624                        // A gap, we can stop here.
2625                        break;
2626                    }
2627                }
2628            } else {
2629                // Process has activities, put it at the very tipsy-top.
2630                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2631                mLruProcesses.add(app);
2632            }
2633            nextIndex = mLruProcessServiceStart;
2634        } else if (hasService) {
2635            // Process has services, put it at the top of the service list.
2636            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2637            mLruProcesses.add(mLruProcessActivityStart, app);
2638            nextIndex = mLruProcessServiceStart;
2639            mLruProcessActivityStart++;
2640        } else  {
2641            // Process not otherwise of interest, it goes to the top of the non-service area.
2642            int index = mLruProcessServiceStart;
2643            if (client != null) {
2644                // If there is a client, don't allow the process to be moved up higher
2645                // in the list than that client.
2646                int clientIndex = mLruProcesses.lastIndexOf(client);
2647                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2648                        + " when updating " + app);
2649                if (clientIndex <= lrui) {
2650                    // Don't allow the client index restriction to push it down farther in the
2651                    // list than it already is.
2652                    clientIndex = lrui;
2653                }
2654                if (clientIndex >= 0 && index > clientIndex) {
2655                    index = clientIndex;
2656                }
2657            }
2658            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2659            mLruProcesses.add(index, app);
2660            nextIndex = index-1;
2661            mLruProcessActivityStart++;
2662            mLruProcessServiceStart++;
2663        }
2664
2665        // If the app is currently using a content provider or service,
2666        // bump those processes as well.
2667        for (int j=app.connections.size()-1; j>=0; j--) {
2668            ConnectionRecord cr = app.connections.valueAt(j);
2669            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2670                    && cr.binding.service.app != null
2671                    && cr.binding.service.app.lruSeq != mLruSeq
2672                    && !cr.binding.service.app.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2674                        "service connection", cr, app);
2675            }
2676        }
2677        for (int j=app.conProviders.size()-1; j>=0; j--) {
2678            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2679            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2680                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2681                        "provider reference", cpr, app);
2682            }
2683        }
2684    }
2685
2686    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2687        if (uid == Process.SYSTEM_UID) {
2688            // The system gets to run in any process.  If there are multiple
2689            // processes with the same uid, just pick the first (this
2690            // should never happen).
2691            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2692            if (procs == null) return null;
2693            final int N = procs.size();
2694            for (int i = 0; i < N; i++) {
2695                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2696            }
2697        }
2698        ProcessRecord proc = mProcessNames.get(processName, uid);
2699        if (false && proc != null && !keepIfLarge
2700                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2701                && proc.lastCachedPss >= 4000) {
2702            // Turn this condition on to cause killing to happen regularly, for testing.
2703            if (proc.baseProcessTracker != null) {
2704                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2705            }
2706            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2707        } else if (proc != null && !keepIfLarge
2708                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2710            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2711            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2712                if (proc.baseProcessTracker != null) {
2713                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714                }
2715                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2716            }
2717        }
2718        return proc;
2719    }
2720
2721    void ensurePackageDexOpt(String packageName) {
2722        IPackageManager pm = AppGlobals.getPackageManager();
2723        try {
2724            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2725                mDidDexOpt = true;
2726            }
2727        } catch (RemoteException e) {
2728        }
2729    }
2730
2731    boolean isNextTransitionForward() {
2732        int transit = mWindowManager.getPendingAppTransition();
2733        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2734                || transit == AppTransition.TRANSIT_TASK_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2736    }
2737
2738    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2739            String processName, String abiOverride, int uid, Runnable crashHandler) {
2740        synchronized(this) {
2741            ApplicationInfo info = new ApplicationInfo();
2742            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2743            // For isolated processes, the former contains the parent's uid and the latter the
2744            // actual uid of the isolated process.
2745            // In the special case introduced by this method (which is, starting an isolated
2746            // process directly from the SystemServer without an actual parent app process) the
2747            // closest thing to a parent's uid is SYSTEM_UID.
2748            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2749            // the |isolated| logic in the ProcessRecord constructor.
2750            info.uid = Process.SYSTEM_UID;
2751            info.processName = processName;
2752            info.className = entryPoint;
2753            info.packageName = "android";
2754            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2755                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2756                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2757                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2758                    crashHandler);
2759            return proc != null ? proc.pid : 0;
2760        }
2761    }
2762
2763    final ProcessRecord startProcessLocked(String processName,
2764            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2765            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2766            boolean isolated, boolean keepIfLarge) {
2767        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2768                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2769                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2770                null /* crashHandler */);
2771    }
2772
2773    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2774            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2775            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2776            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2777        long startTime = SystemClock.elapsedRealtime();
2778        ProcessRecord app;
2779        if (!isolated) {
2780            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2781            checkTime(startTime, "startProcess: after getProcessRecord");
2782        } else {
2783            // If this is an isolated process, it can't re-use an existing process.
2784            app = null;
2785        }
2786        // We don't have to do anything more if:
2787        // (1) There is an existing application record; and
2788        // (2) The caller doesn't think it is dead, OR there is no thread
2789        //     object attached to it so we know it couldn't have crashed; and
2790        // (3) There is a pid assigned to it, so it is either starting or
2791        //     already running.
2792        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2793                + " app=" + app + " knownToBeDead=" + knownToBeDead
2794                + " thread=" + (app != null ? app.thread : null)
2795                + " pid=" + (app != null ? app.pid : -1));
2796        if (app != null && app.pid > 0) {
2797            if (!knownToBeDead || app.thread == null) {
2798                // We already have the app running, or are waiting for it to
2799                // come up (we have a pid but not yet its thread), so keep it.
2800                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2801                // If this is a new package in the process, add the package to the list
2802                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2803                checkTime(startTime, "startProcess: done, added package to proc");
2804                return app;
2805            }
2806
2807            // An application record is attached to a previous process,
2808            // clean it up now.
2809            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2810            checkTime(startTime, "startProcess: bad proc running, killing");
2811            Process.killProcessGroup(app.info.uid, app.pid);
2812            handleAppDiedLocked(app, true, true);
2813            checkTime(startTime, "startProcess: done killing old proc");
2814        }
2815
2816        String hostingNameStr = hostingName != null
2817                ? hostingName.flattenToShortString() : null;
2818
2819        if (!isolated) {
2820            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2821                // If we are in the background, then check to see if this process
2822                // is bad.  If so, we will just silently fail.
2823                if (mBadProcesses.get(info.processName, info.uid) != null) {
2824                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2825                            + "/" + info.processName);
2826                    return null;
2827                }
2828            } else {
2829                // When the user is explicitly starting a process, then clear its
2830                // crash count so that we won't make it bad until they see at
2831                // least one crash dialog again, and make the process good again
2832                // if it had been bad.
2833                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2834                        + "/" + info.processName);
2835                mProcessCrashTimes.remove(info.processName, info.uid);
2836                if (mBadProcesses.get(info.processName, info.uid) != null) {
2837                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2838                            UserHandle.getUserId(info.uid), info.uid,
2839                            info.processName);
2840                    mBadProcesses.remove(info.processName, info.uid);
2841                    if (app != null) {
2842                        app.bad = false;
2843                    }
2844                }
2845            }
2846        }
2847
2848        if (app == null) {
2849            checkTime(startTime, "startProcess: creating new process record");
2850            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2851            if (app == null) {
2852                Slog.w(TAG, "Failed making new process record for "
2853                        + processName + "/" + info.uid + " isolated=" + isolated);
2854                return null;
2855            }
2856            app.crashHandler = crashHandler;
2857            mProcessNames.put(processName, app.uid, app);
2858            if (isolated) {
2859                mIsolatedProcesses.put(app.uid, app);
2860            }
2861            checkTime(startTime, "startProcess: done creating new process record");
2862        } else {
2863            // If this is a new package in the process, add the package to the list
2864            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2865            checkTime(startTime, "startProcess: added package to existing proc");
2866        }
2867
2868        // If the system is not ready yet, then hold off on starting this
2869        // process until it is.
2870        if (!mProcessesReady
2871                && !isAllowedWhileBooting(info)
2872                && !allowWhileBooting) {
2873            if (!mProcessesOnHold.contains(app)) {
2874                mProcessesOnHold.add(app);
2875            }
2876            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2877            checkTime(startTime, "startProcess: returning with proc on hold");
2878            return app;
2879        }
2880
2881        checkTime(startTime, "startProcess: stepping in to startProcess");
2882        startProcessLocked(
2883                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2884        checkTime(startTime, "startProcess: done starting proc!");
2885        return (app.pid != 0) ? app : null;
2886    }
2887
2888    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2889        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2890    }
2891
2892    private final void startProcessLocked(ProcessRecord app,
2893            String hostingType, String hostingNameStr) {
2894        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2895                null /* entryPoint */, null /* entryPointArgs */);
2896    }
2897
2898    private final void startProcessLocked(ProcessRecord app, String hostingType,
2899            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2900        long startTime = SystemClock.elapsedRealtime();
2901        if (app.pid > 0 && app.pid != MY_PID) {
2902            checkTime(startTime, "startProcess: removing from pids map");
2903            synchronized (mPidsSelfLocked) {
2904                mPidsSelfLocked.remove(app.pid);
2905                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2906            }
2907            checkTime(startTime, "startProcess: done removing from pids map");
2908            app.setPid(0);
2909        }
2910
2911        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2912                "startProcessLocked removing on hold: " + app);
2913        mProcessesOnHold.remove(app);
2914
2915        checkTime(startTime, "startProcess: starting to update cpu stats");
2916        updateCpuStats();
2917        checkTime(startTime, "startProcess: done updating cpu stats");
2918
2919        try {
2920            int uid = app.uid;
2921
2922            int[] gids = null;
2923            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2924            if (!app.isolated) {
2925                int[] permGids = null;
2926                try {
2927                    checkTime(startTime, "startProcess: getting gids from package manager");
2928                    final PackageManager pm = mContext.getPackageManager();
2929                    permGids = pm.getPackageGids(app.info.packageName);
2930
2931                    if (Environment.isExternalStorageEmulated()) {
2932                        checkTime(startTime, "startProcess: checking external storage perm");
2933                        if (pm.checkPermission(
2934                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2935                                app.info.packageName) == PERMISSION_GRANTED) {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2937                        } else {
2938                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2939                        }
2940                    }
2941                } catch (PackageManager.NameNotFoundException e) {
2942                    Slog.w(TAG, "Unable to retrieve gids", e);
2943                }
2944
2945                /*
2946                 * Add shared application and profile GIDs so applications can share some
2947                 * resources like shared libraries and access user-wide resources
2948                 */
2949                if (permGids == null) {
2950                    gids = new int[2];
2951                } else {
2952                    gids = new int[permGids.length + 2];
2953                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2954                }
2955                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2956                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2957            }
2958            checkTime(startTime, "startProcess: building args");
2959            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2960                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2961                        && mTopComponent != null
2962                        && app.processName.equals(mTopComponent.getPackageName())) {
2963                    uid = 0;
2964                }
2965                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2966                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2967                    uid = 0;
2968                }
2969            }
2970            int debugFlags = 0;
2971            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2972                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2973                // Also turn on CheckJNI for debuggable apps. It's quite
2974                // awkward to turn on otherwise.
2975                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2976            }
2977            // Run the app in safe mode if its manifest requests so or the
2978            // system is booted in safe mode.
2979            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2980                mSafeMode == true) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2982            }
2983            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2988            }
2989            if ("1".equals(SystemProperties.get("debug.assert"))) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2991            }
2992
2993            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2994            if (requiredAbi == null) {
2995                requiredAbi = Build.SUPPORTED_ABIS[0];
2996            }
2997
2998            String instructionSet = null;
2999            if (app.info.primaryCpuAbi != null) {
3000                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3001            }
3002
3003            app.gids = gids;
3004            app.requiredAbi = requiredAbi;
3005            app.instructionSet = instructionSet;
3006
3007            // Start the process.  It will either succeed and return a result containing
3008            // the PID of the new process, or else throw a RuntimeException.
3009            boolean isActivityProcess = (entryPoint == null);
3010            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3011            checkTime(startTime, "startProcess: asking zygote to start proc");
3012            Process.ProcessStartResult startResult = Process.start(entryPoint,
3013                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3014                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3015                    app.info.dataDir, entryPointArgs);
3016            checkTime(startTime, "startProcess: returned from zygote!");
3017
3018            if (app.isolated) {
3019                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3020            }
3021            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3022            checkTime(startTime, "startProcess: done updating battery stats");
3023
3024            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3025                    UserHandle.getUserId(uid), startResult.pid, uid,
3026                    app.processName, hostingType,
3027                    hostingNameStr != null ? hostingNameStr : "");
3028
3029            if (app.persistent) {
3030                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3031            }
3032
3033            checkTime(startTime, "startProcess: building log message");
3034            StringBuilder buf = mStringBuilder;
3035            buf.setLength(0);
3036            buf.append("Start proc ");
3037            buf.append(startResult.pid);
3038            buf.append(':');
3039            buf.append(app.processName);
3040            buf.append('/');
3041            UserHandle.formatUid(buf, uid);
3042            if (!isActivityProcess) {
3043                buf.append(" [");
3044                buf.append(entryPoint);
3045                buf.append("]");
3046            }
3047            buf.append(" for ");
3048            buf.append(hostingType);
3049            if (hostingNameStr != null) {
3050                buf.append(" ");
3051                buf.append(hostingNameStr);
3052            }
3053            Slog.i(TAG, buf.toString());
3054            app.setPid(startResult.pid);
3055            app.usingWrapper = startResult.usingWrapper;
3056            app.removed = false;
3057            app.killed = false;
3058            app.killedByAm = false;
3059            checkTime(startTime, "startProcess: starting to update pids map");
3060            synchronized (mPidsSelfLocked) {
3061                this.mPidsSelfLocked.put(startResult.pid, app);
3062                if (isActivityProcess) {
3063                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3064                    msg.obj = app;
3065                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3066                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3067                }
3068            }
3069            checkTime(startTime, "startProcess: done updating pids map");
3070        } catch (RuntimeException e) {
3071            // XXX do better error recovery.
3072            app.setPid(0);
3073            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3074            if (app.isolated) {
3075                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3076            }
3077            Slog.e(TAG, "Failure starting process " + app.processName, e);
3078        }
3079    }
3080
3081    void updateUsageStats(ActivityRecord component, boolean resumed) {
3082        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3083        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3084        if (resumed) {
3085            if (mUsageStatsService != null) {
3086                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3087                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3088            }
3089            synchronized (stats) {
3090                stats.noteActivityResumedLocked(component.app.uid);
3091            }
3092        } else {
3093            if (mUsageStatsService != null) {
3094                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3095                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3096            }
3097            synchronized (stats) {
3098                stats.noteActivityPausedLocked(component.app.uid);
3099            }
3100        }
3101    }
3102
3103    Intent getHomeIntent() {
3104        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3105        intent.setComponent(mTopComponent);
3106        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3107            intent.addCategory(Intent.CATEGORY_HOME);
3108        }
3109        return intent;
3110    }
3111
3112    boolean startHomeActivityLocked(int userId, String reason) {
3113        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3114                && mTopAction == null) {
3115            // We are running in factory test mode, but unable to find
3116            // the factory test app, so just sit around displaying the
3117            // error message and don't try to start anything.
3118            return false;
3119        }
3120        Intent intent = getHomeIntent();
3121        ActivityInfo aInfo =
3122            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3123        if (aInfo != null) {
3124            intent.setComponent(new ComponentName(
3125                    aInfo.applicationInfo.packageName, aInfo.name));
3126            // Don't do this if the home app is currently being
3127            // instrumented.
3128            aInfo = new ActivityInfo(aInfo);
3129            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3130            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3131                    aInfo.applicationInfo.uid, true);
3132            if (app == null || app.instrumentationClass == null) {
3133                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3134                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3135            }
3136        }
3137
3138        return true;
3139    }
3140
3141    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3142        ActivityInfo ai = null;
3143        ComponentName comp = intent.getComponent();
3144        try {
3145            if (comp != null) {
3146                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3147            } else {
3148                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3149                        intent,
3150                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3151                            flags, userId);
3152
3153                if (info != null) {
3154                    ai = info.activityInfo;
3155                }
3156            }
3157        } catch (RemoteException e) {
3158            // ignore
3159        }
3160
3161        return ai;
3162    }
3163
3164    /**
3165     * Starts the "new version setup screen" if appropriate.
3166     */
3167    void startSetupActivityLocked() {
3168        // Only do this once per boot.
3169        if (mCheckedForSetup) {
3170            return;
3171        }
3172
3173        // We will show this screen if the current one is a different
3174        // version than the last one shown, and we are not running in
3175        // low-level factory test mode.
3176        final ContentResolver resolver = mContext.getContentResolver();
3177        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3178                Settings.Global.getInt(resolver,
3179                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3180            mCheckedForSetup = true;
3181
3182            // See if we should be showing the platform update setup UI.
3183            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3184            List<ResolveInfo> ris = mContext.getPackageManager()
3185                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3186
3187            // We don't allow third party apps to replace this.
3188            ResolveInfo ri = null;
3189            for (int i=0; ris != null && i<ris.size(); i++) {
3190                if ((ris.get(i).activityInfo.applicationInfo.flags
3191                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3192                    ri = ris.get(i);
3193                    break;
3194                }
3195            }
3196
3197            if (ri != null) {
3198                String vers = ri.activityInfo.metaData != null
3199                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3200                        : null;
3201                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3202                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3203                            Intent.METADATA_SETUP_VERSION);
3204                }
3205                String lastVers = Settings.Secure.getString(
3206                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3207                if (vers != null && !vers.equals(lastVers)) {
3208                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3209                    intent.setComponent(new ComponentName(
3210                            ri.activityInfo.packageName, ri.activityInfo.name));
3211                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3212                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3213                            null);
3214                }
3215            }
3216        }
3217    }
3218
3219    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3220        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3221    }
3222
3223    void enforceNotIsolatedCaller(String caller) {
3224        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3225            throw new SecurityException("Isolated process not allowed to call " + caller);
3226        }
3227    }
3228
3229    void enforceShellRestriction(String restriction, int userHandle) {
3230        if (Binder.getCallingUid() == Process.SHELL_UID) {
3231            if (userHandle < 0
3232                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3233                throw new SecurityException("Shell does not have permission to access user "
3234                        + userHandle);
3235            }
3236        }
3237    }
3238
3239    @Override
3240    public int getFrontActivityScreenCompatMode() {
3241        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3242        synchronized (this) {
3243            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3244        }
3245    }
3246
3247    @Override
3248    public void setFrontActivityScreenCompatMode(int mode) {
3249        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3250                "setFrontActivityScreenCompatMode");
3251        synchronized (this) {
3252            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3253        }
3254    }
3255
3256    @Override
3257    public int getPackageScreenCompatMode(String packageName) {
3258        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3259        synchronized (this) {
3260            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3261        }
3262    }
3263
3264    @Override
3265    public void setPackageScreenCompatMode(String packageName, int mode) {
3266        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3267                "setPackageScreenCompatMode");
3268        synchronized (this) {
3269            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3270        }
3271    }
3272
3273    @Override
3274    public boolean getPackageAskScreenCompat(String packageName) {
3275        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3276        synchronized (this) {
3277            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3278        }
3279    }
3280
3281    @Override
3282    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3283        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3284                "setPackageAskScreenCompat");
3285        synchronized (this) {
3286            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3287        }
3288    }
3289
3290    private void dispatchProcessesChanged() {
3291        int N;
3292        synchronized (this) {
3293            N = mPendingProcessChanges.size();
3294            if (mActiveProcessChanges.length < N) {
3295                mActiveProcessChanges = new ProcessChangeItem[N];
3296            }
3297            mPendingProcessChanges.toArray(mActiveProcessChanges);
3298            mAvailProcessChanges.addAll(mPendingProcessChanges);
3299            mPendingProcessChanges.clear();
3300            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3301        }
3302
3303        int i = mProcessObservers.beginBroadcast();
3304        while (i > 0) {
3305            i--;
3306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3307            if (observer != null) {
3308                try {
3309                    for (int j=0; j<N; j++) {
3310                        ProcessChangeItem item = mActiveProcessChanges[j];
3311                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3312                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3313                                    + item.pid + " uid=" + item.uid + ": "
3314                                    + item.foregroundActivities);
3315                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3316                                    item.foregroundActivities);
3317                        }
3318                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3319                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3320                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3321                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3322                        }
3323                    }
3324                } catch (RemoteException e) {
3325                }
3326            }
3327        }
3328        mProcessObservers.finishBroadcast();
3329    }
3330
3331    private void dispatchProcessDied(int pid, int uid) {
3332        int i = mProcessObservers.beginBroadcast();
3333        while (i > 0) {
3334            i--;
3335            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3336            if (observer != null) {
3337                try {
3338                    observer.onProcessDied(pid, uid);
3339                } catch (RemoteException e) {
3340                }
3341            }
3342        }
3343        mProcessObservers.finishBroadcast();
3344    }
3345
3346    @Override
3347    public final int startActivity(IApplicationThread caller, String callingPackage,
3348            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3349            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3350        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3351            resultWho, requestCode, startFlags, profilerInfo, options,
3352            UserHandle.getCallingUserId());
3353    }
3354
3355    @Override
3356    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3357            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3358            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3359        enforceNotIsolatedCaller("startActivity");
3360        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3361                false, ALLOW_FULL_ONLY, "startActivity", null);
3362        // TODO: Switch to user app stacks here.
3363        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3364                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3365                profilerInfo, null, null, options, userId, null, null);
3366    }
3367
3368    @Override
3369    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3370            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3371            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3372
3373        // This is very dangerous -- it allows you to perform a start activity (including
3374        // permission grants) as any app that may launch one of your own activities.  So
3375        // we will only allow this to be done from activities that are part of the core framework,
3376        // and then only when they are running as the system.
3377        final ActivityRecord sourceRecord;
3378        final int targetUid;
3379        final String targetPackage;
3380        synchronized (this) {
3381            if (resultTo == null) {
3382                throw new SecurityException("Must be called from an activity");
3383            }
3384            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3385            if (sourceRecord == null) {
3386                throw new SecurityException("Called with bad activity token: " + resultTo);
3387            }
3388            if (!sourceRecord.info.packageName.equals("android")) {
3389                throw new SecurityException(
3390                        "Must be called from an activity that is declared in the android package");
3391            }
3392            if (sourceRecord.app == null) {
3393                throw new SecurityException("Called without a process attached to activity");
3394            }
3395            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3396                // This is still okay, as long as this activity is running under the
3397                // uid of the original calling activity.
3398                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3399                    throw new SecurityException(
3400                            "Calling activity in uid " + sourceRecord.app.uid
3401                                    + " must be system uid or original calling uid "
3402                                    + sourceRecord.launchedFromUid);
3403                }
3404            }
3405            targetUid = sourceRecord.launchedFromUid;
3406            targetPackage = sourceRecord.launchedFromPackage;
3407        }
3408
3409        if (userId == UserHandle.USER_NULL) {
3410            userId = UserHandle.getUserId(sourceRecord.app.uid);
3411        }
3412
3413        // TODO: Switch to user app stacks here.
3414        try {
3415            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3416                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3417                    null, null, options, userId, null, null);
3418            return ret;
3419        } catch (SecurityException e) {
3420            // XXX need to figure out how to propagate to original app.
3421            // A SecurityException here is generally actually a fault of the original
3422            // calling activity (such as a fairly granting permissions), so propagate it
3423            // back to them.
3424            /*
3425            StringBuilder msg = new StringBuilder();
3426            msg.append("While launching");
3427            msg.append(intent.toString());
3428            msg.append(": ");
3429            msg.append(e.getMessage());
3430            */
3431            throw e;
3432        }
3433    }
3434
3435    @Override
3436    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3437            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3438            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3439        enforceNotIsolatedCaller("startActivityAndWait");
3440        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3441                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3442        WaitResult res = new WaitResult();
3443        // TODO: Switch to user app stacks here.
3444        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3445                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3446                options, userId, null, null);
3447        return res;
3448    }
3449
3450    @Override
3451    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3452            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3453            int startFlags, Configuration config, Bundle options, int userId) {
3454        enforceNotIsolatedCaller("startActivityWithConfig");
3455        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3456                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3457        // TODO: Switch to user app stacks here.
3458        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3459                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3460                null, null, config, options, userId, null, null);
3461        return ret;
3462    }
3463
3464    @Override
3465    public int startActivityIntentSender(IApplicationThread caller,
3466            IntentSender intent, Intent fillInIntent, String resolvedType,
3467            IBinder resultTo, String resultWho, int requestCode,
3468            int flagsMask, int flagsValues, Bundle options) {
3469        enforceNotIsolatedCaller("startActivityIntentSender");
3470        // Refuse possible leaked file descriptors
3471        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3472            throw new IllegalArgumentException("File descriptors passed in Intent");
3473        }
3474
3475        IIntentSender sender = intent.getTarget();
3476        if (!(sender instanceof PendingIntentRecord)) {
3477            throw new IllegalArgumentException("Bad PendingIntent object");
3478        }
3479
3480        PendingIntentRecord pir = (PendingIntentRecord)sender;
3481
3482        synchronized (this) {
3483            // If this is coming from the currently resumed activity, it is
3484            // effectively saying that app switches are allowed at this point.
3485            final ActivityStack stack = getFocusedStack();
3486            if (stack.mResumedActivity != null &&
3487                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3488                mAppSwitchesAllowedTime = 0;
3489            }
3490        }
3491        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3492                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3493        return ret;
3494    }
3495
3496    @Override
3497    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3498            Intent intent, String resolvedType, IVoiceInteractionSession session,
3499            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3500            Bundle options, int userId) {
3501        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3502                != PackageManager.PERMISSION_GRANTED) {
3503            String msg = "Permission Denial: startVoiceActivity() from pid="
3504                    + Binder.getCallingPid()
3505                    + ", uid=" + Binder.getCallingUid()
3506                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3507            Slog.w(TAG, msg);
3508            throw new SecurityException(msg);
3509        }
3510        if (session == null || interactor == null) {
3511            throw new NullPointerException("null session or interactor");
3512        }
3513        userId = handleIncomingUser(callingPid, callingUid, userId,
3514                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3515        // TODO: Switch to user app stacks here.
3516        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3517                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3518                null, options, userId, null, null);
3519    }
3520
3521    @Override
3522    public boolean startNextMatchingActivity(IBinder callingActivity,
3523            Intent intent, Bundle options) {
3524        // Refuse possible leaked file descriptors
3525        if (intent != null && intent.hasFileDescriptors() == true) {
3526            throw new IllegalArgumentException("File descriptors passed in Intent");
3527        }
3528
3529        synchronized (this) {
3530            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3531            if (r == null) {
3532                ActivityOptions.abort(options);
3533                return false;
3534            }
3535            if (r.app == null || r.app.thread == null) {
3536                // The caller is not running...  d'oh!
3537                ActivityOptions.abort(options);
3538                return false;
3539            }
3540            intent = new Intent(intent);
3541            // The caller is not allowed to change the data.
3542            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3543            // And we are resetting to find the next component...
3544            intent.setComponent(null);
3545
3546            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3547
3548            ActivityInfo aInfo = null;
3549            try {
3550                List<ResolveInfo> resolves =
3551                    AppGlobals.getPackageManager().queryIntentActivities(
3552                            intent, r.resolvedType,
3553                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3554                            UserHandle.getCallingUserId());
3555
3556                // Look for the original activity in the list...
3557                final int N = resolves != null ? resolves.size() : 0;
3558                for (int i=0; i<N; i++) {
3559                    ResolveInfo rInfo = resolves.get(i);
3560                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3561                            && rInfo.activityInfo.name.equals(r.info.name)) {
3562                        // We found the current one...  the next matching is
3563                        // after it.
3564                        i++;
3565                        if (i<N) {
3566                            aInfo = resolves.get(i).activityInfo;
3567                        }
3568                        if (debug) {
3569                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3570                                    + "/" + r.info.name);
3571                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3572                                    + "/" + aInfo.name);
3573                        }
3574                        break;
3575                    }
3576                }
3577            } catch (RemoteException e) {
3578            }
3579
3580            if (aInfo == null) {
3581                // Nobody who is next!
3582                ActivityOptions.abort(options);
3583                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3584                return false;
3585            }
3586
3587            intent.setComponent(new ComponentName(
3588                    aInfo.applicationInfo.packageName, aInfo.name));
3589            intent.setFlags(intent.getFlags()&~(
3590                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3591                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3592                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3593                    Intent.FLAG_ACTIVITY_NEW_TASK));
3594
3595            // Okay now we need to start the new activity, replacing the
3596            // currently running activity.  This is a little tricky because
3597            // we want to start the new one as if the current one is finished,
3598            // but not finish the current one first so that there is no flicker.
3599            // And thus...
3600            final boolean wasFinishing = r.finishing;
3601            r.finishing = true;
3602
3603            // Propagate reply information over to the new activity.
3604            final ActivityRecord resultTo = r.resultTo;
3605            final String resultWho = r.resultWho;
3606            final int requestCode = r.requestCode;
3607            r.resultTo = null;
3608            if (resultTo != null) {
3609                resultTo.removeResultsLocked(r, resultWho, requestCode);
3610            }
3611
3612            final long origId = Binder.clearCallingIdentity();
3613            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3614                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3615                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3616                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3617            Binder.restoreCallingIdentity(origId);
3618
3619            r.finishing = wasFinishing;
3620            if (res != ActivityManager.START_SUCCESS) {
3621                return false;
3622            }
3623            return true;
3624        }
3625    }
3626
3627    @Override
3628    public final int startActivityFromRecents(int taskId, Bundle options) {
3629        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3630            String msg = "Permission Denial: startActivityFromRecents called without " +
3631                    START_TASKS_FROM_RECENTS;
3632            Slog.w(TAG, msg);
3633            throw new SecurityException(msg);
3634        }
3635        return startActivityFromRecentsInner(taskId, options);
3636    }
3637
3638    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3639        final TaskRecord task;
3640        final int callingUid;
3641        final String callingPackage;
3642        final Intent intent;
3643        final int userId;
3644        synchronized (this) {
3645            task = recentTaskForIdLocked(taskId);
3646            if (task == null) {
3647                throw new IllegalArgumentException("Task " + taskId + " not found.");
3648            }
3649            if (task.getRootActivity() != null) {
3650                moveTaskToFrontLocked(task.taskId, 0, null);
3651                return ActivityManager.START_TASK_TO_FRONT;
3652            }
3653            callingUid = task.mCallingUid;
3654            callingPackage = task.mCallingPackage;
3655            intent = task.intent;
3656            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3657            userId = task.userId;
3658        }
3659        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3660                options, userId, null, task);
3661    }
3662
3663    final int startActivityInPackage(int uid, String callingPackage,
3664            Intent intent, String resolvedType, IBinder resultTo,
3665            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3666            IActivityContainer container, TaskRecord inTask) {
3667
3668        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3669                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3670
3671        // TODO: Switch to user app stacks here.
3672        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3673                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3674                null, null, null, options, userId, container, inTask);
3675        return ret;
3676    }
3677
3678    @Override
3679    public final int startActivities(IApplicationThread caller, String callingPackage,
3680            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3681            int userId) {
3682        enforceNotIsolatedCaller("startActivities");
3683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3684                false, ALLOW_FULL_ONLY, "startActivity", null);
3685        // TODO: Switch to user app stacks here.
3686        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3687                resolvedTypes, resultTo, options, userId);
3688        return ret;
3689    }
3690
3691    final int startActivitiesInPackage(int uid, String callingPackage,
3692            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3693            Bundle options, int userId) {
3694
3695        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3696                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3697        // TODO: Switch to user app stacks here.
3698        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3699                resultTo, options, userId);
3700        return ret;
3701    }
3702
3703    //explicitly remove thd old information in mRecentTasks when removing existing user.
3704    private void removeRecentTasksForUserLocked(int userId) {
3705        if(userId <= 0) {
3706            Slog.i(TAG, "Can't remove recent task on user " + userId);
3707            return;
3708        }
3709
3710        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3711            TaskRecord tr = mRecentTasks.get(i);
3712            if (tr.userId == userId) {
3713                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3714                        + " when finishing user" + userId);
3715                mRecentTasks.remove(i);
3716                tr.removedFromRecents();
3717            }
3718        }
3719
3720        // Remove tasks from persistent storage.
3721        notifyTaskPersisterLocked(null, true);
3722    }
3723
3724    // Sort by taskId
3725    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3726        @Override
3727        public int compare(TaskRecord lhs, TaskRecord rhs) {
3728            return rhs.taskId - lhs.taskId;
3729        }
3730    };
3731
3732    // Extract the affiliates of the chain containing mRecentTasks[start].
3733    private int processNextAffiliateChainLocked(int start) {
3734        final TaskRecord startTask = mRecentTasks.get(start);
3735        final int affiliateId = startTask.mAffiliatedTaskId;
3736
3737        // Quick identification of isolated tasks. I.e. those not launched behind.
3738        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3739                startTask.mNextAffiliate == null) {
3740            // There is still a slim chance that there are other tasks that point to this task
3741            // and that the chain is so messed up that this task no longer points to them but
3742            // the gain of this optimization outweighs the risk.
3743            startTask.inRecents = true;
3744            return start + 1;
3745        }
3746
3747        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3748        mTmpRecents.clear();
3749        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3750            final TaskRecord task = mRecentTasks.get(i);
3751            if (task.mAffiliatedTaskId == affiliateId) {
3752                mRecentTasks.remove(i);
3753                mTmpRecents.add(task);
3754            }
3755        }
3756
3757        // Sort them all by taskId. That is the order they were create in and that order will
3758        // always be correct.
3759        Collections.sort(mTmpRecents, mTaskRecordComparator);
3760
3761        // Go through and fix up the linked list.
3762        // The first one is the end of the chain and has no next.
3763        final TaskRecord first = mTmpRecents.get(0);
3764        first.inRecents = true;
3765        if (first.mNextAffiliate != null) {
3766            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3767            first.setNextAffiliate(null);
3768            notifyTaskPersisterLocked(first, false);
3769        }
3770        // Everything in the middle is doubly linked from next to prev.
3771        final int tmpSize = mTmpRecents.size();
3772        for (int i = 0; i < tmpSize - 1; ++i) {
3773            final TaskRecord next = mTmpRecents.get(i);
3774            final TaskRecord prev = mTmpRecents.get(i + 1);
3775            if (next.mPrevAffiliate != prev) {
3776                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3777                        " setting prev=" + prev);
3778                next.setPrevAffiliate(prev);
3779                notifyTaskPersisterLocked(next, false);
3780            }
3781            if (prev.mNextAffiliate != next) {
3782                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3783                        " setting next=" + next);
3784                prev.setNextAffiliate(next);
3785                notifyTaskPersisterLocked(prev, false);
3786            }
3787            prev.inRecents = true;
3788        }
3789        // The last one is the beginning of the list and has no prev.
3790        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3791        if (last.mPrevAffiliate != null) {
3792            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3793            last.setPrevAffiliate(null);
3794            notifyTaskPersisterLocked(last, false);
3795        }
3796
3797        // Insert the group back into mRecentTasks at start.
3798        mRecentTasks.addAll(start, mTmpRecents);
3799
3800        // Let the caller know where we left off.
3801        return start + tmpSize;
3802    }
3803
3804    /**
3805     * Update the recent tasks lists: make sure tasks should still be here (their
3806     * applications / activities still exist), update their availability, fixup ordering
3807     * of affiliations.
3808     */
3809    void cleanupRecentTasksLocked(int userId) {
3810        if (mRecentTasks == null) {
3811            // Happens when called from the packagemanager broadcast before boot.
3812            return;
3813        }
3814
3815        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3816        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3817        final IPackageManager pm = AppGlobals.getPackageManager();
3818        final ActivityInfo dummyAct = new ActivityInfo();
3819        final ApplicationInfo dummyApp = new ApplicationInfo();
3820
3821        int N = mRecentTasks.size();
3822
3823        int[] users = userId == UserHandle.USER_ALL
3824                ? getUsersLocked() : new int[] { userId };
3825        for (int user : users) {
3826            for (int i = 0; i < N; i++) {
3827                TaskRecord task = mRecentTasks.get(i);
3828                if (task.userId != user) {
3829                    // Only look at tasks for the user ID of interest.
3830                    continue;
3831                }
3832                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3833                    // This situation is broken, and we should just get rid of it now.
3834                    mRecentTasks.remove(i);
3835                    task.removedFromRecents();
3836                    i--;
3837                    N--;
3838                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3839                    continue;
3840                }
3841                // Check whether this activity is currently available.
3842                if (task.realActivity != null) {
3843                    ActivityInfo ai = availActCache.get(task.realActivity);
3844                    if (ai == null) {
3845                        try {
3846                            ai = pm.getActivityInfo(task.realActivity,
3847                                    PackageManager.GET_UNINSTALLED_PACKAGES
3848                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3849                        } catch (RemoteException e) {
3850                            // Will never happen.
3851                            continue;
3852                        }
3853                        if (ai == null) {
3854                            ai = dummyAct;
3855                        }
3856                        availActCache.put(task.realActivity, ai);
3857                    }
3858                    if (ai == dummyAct) {
3859                        // This could be either because the activity no longer exists, or the
3860                        // app is temporarily gone.  For the former we want to remove the recents
3861                        // entry; for the latter we want to mark it as unavailable.
3862                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3863                        if (app == null) {
3864                            try {
3865                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3866                                        PackageManager.GET_UNINSTALLED_PACKAGES
3867                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3868                            } catch (RemoteException e) {
3869                                // Will never happen.
3870                                continue;
3871                            }
3872                            if (app == null) {
3873                                app = dummyApp;
3874                            }
3875                            availAppCache.put(task.realActivity.getPackageName(), app);
3876                        }
3877                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3878                            // Doesn't exist any more!  Good-bye.
3879                            mRecentTasks.remove(i);
3880                            task.removedFromRecents();
3881                            i--;
3882                            N--;
3883                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3884                            continue;
3885                        } else {
3886                            // Otherwise just not available for now.
3887                            if (task.isAvailable) {
3888                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3889                                        + task);
3890                            }
3891                            task.isAvailable = false;
3892                        }
3893                    } else {
3894                        if (!ai.enabled || !ai.applicationInfo.enabled
3895                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3896                            if (task.isAvailable) {
3897                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3898                                        + task + " (enabled=" + ai.enabled + "/"
3899                                        + ai.applicationInfo.enabled +  " flags="
3900                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3901                            }
3902                            task.isAvailable = false;
3903                        } else {
3904                            if (!task.isAvailable) {
3905                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3906                                        + task);
3907                            }
3908                            task.isAvailable = true;
3909                        }
3910                    }
3911                }
3912            }
3913        }
3914
3915        // Verify the affiliate chain for each task.
3916        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3917        }
3918
3919        mTmpRecents.clear();
3920        // mRecentTasks is now in sorted, affiliated order.
3921    }
3922
3923    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3924        int N = mRecentTasks.size();
3925        TaskRecord top = task;
3926        int topIndex = taskIndex;
3927        while (top.mNextAffiliate != null && topIndex > 0) {
3928            top = top.mNextAffiliate;
3929            topIndex--;
3930        }
3931        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3932                + topIndex + " from intial " + taskIndex);
3933        // Find the end of the chain, doing a sanity check along the way.
3934        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3935        int endIndex = topIndex;
3936        TaskRecord prev = top;
3937        while (endIndex < N) {
3938            TaskRecord cur = mRecentTasks.get(endIndex);
3939            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3940                    + endIndex + " " + cur);
3941            if (cur == top) {
3942                // Verify start of the chain.
3943                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3944                    Slog.wtf(TAG, "Bad chain @" + endIndex
3945                            + ": first task has next affiliate: " + prev);
3946                    sane = false;
3947                    break;
3948                }
3949            } else {
3950                // Verify middle of the chain's next points back to the one before.
3951                if (cur.mNextAffiliate != prev
3952                        || cur.mNextAffiliateTaskId != prev.taskId) {
3953                    Slog.wtf(TAG, "Bad chain @" + endIndex
3954                            + ": middle task " + cur + " @" + endIndex
3955                            + " has bad next affiliate "
3956                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3957                            + ", expected " + prev);
3958                    sane = false;
3959                    break;
3960                }
3961            }
3962            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3963                // Chain ends here.
3964                if (cur.mPrevAffiliate != null) {
3965                    Slog.wtf(TAG, "Bad chain @" + endIndex
3966                            + ": last task " + cur + " has previous affiliate "
3967                            + cur.mPrevAffiliate);
3968                    sane = false;
3969                }
3970                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3971                break;
3972            } else {
3973                // Verify middle of the chain's prev points to a valid item.
3974                if (cur.mPrevAffiliate == null) {
3975                    Slog.wtf(TAG, "Bad chain @" + endIndex
3976                            + ": task " + cur + " has previous affiliate "
3977                            + cur.mPrevAffiliate + " but should be id "
3978                            + cur.mPrevAffiliate);
3979                    sane = false;
3980                    break;
3981                }
3982            }
3983            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3984                Slog.wtf(TAG, "Bad chain @" + endIndex
3985                        + ": task " + cur + " has affiliated id "
3986                        + cur.mAffiliatedTaskId + " but should be "
3987                        + task.mAffiliatedTaskId);
3988                sane = false;
3989                break;
3990            }
3991            prev = cur;
3992            endIndex++;
3993            if (endIndex >= N) {
3994                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3995                        + ": last task " + prev);
3996                sane = false;
3997                break;
3998            }
3999        }
4000        if (sane) {
4001            if (endIndex < taskIndex) {
4002                Slog.wtf(TAG, "Bad chain @" + endIndex
4003                        + ": did not extend to task " + task + " @" + taskIndex);
4004                sane = false;
4005            }
4006        }
4007        if (sane) {
4008            // All looks good, we can just move all of the affiliated tasks
4009            // to the top.
4010            for (int i=topIndex; i<=endIndex; i++) {
4011                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4012                        + " from " + i + " to " + (i-topIndex));
4013                TaskRecord cur = mRecentTasks.remove(i);
4014                mRecentTasks.add(i-topIndex, cur);
4015            }
4016            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4017                    + " to " + endIndex);
4018            return true;
4019        }
4020
4021        // Whoops, couldn't do it.
4022        return false;
4023    }
4024
4025    final void addRecentTaskLocked(TaskRecord task) {
4026        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4027                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4028                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4029
4030        int N = mRecentTasks.size();
4031        // Quick case: check if the top-most recent task is the same.
4032        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4033            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4034            return;
4035        }
4036        // Another quick case: check if this is part of a set of affiliated
4037        // tasks that are at the top.
4038        if (isAffiliated && N > 0 && task.inRecents
4039                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4040            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4041                    + " at top when adding " + task);
4042            return;
4043        }
4044        // Another quick case: never add voice sessions.
4045        if (task.voiceSession != null) {
4046            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4047            return;
4048        }
4049
4050        boolean needAffiliationFix = false;
4051
4052        // Slightly less quick case: the task is already in recents, so all we need
4053        // to do is move it.
4054        if (task.inRecents) {
4055            int taskIndex = mRecentTasks.indexOf(task);
4056            if (taskIndex >= 0) {
4057                if (!isAffiliated) {
4058                    // Simple case: this is not an affiliated task, so we just move it to the front.
4059                    mRecentTasks.remove(taskIndex);
4060                    mRecentTasks.add(0, task);
4061                    notifyTaskPersisterLocked(task, false);
4062                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4063                            + " from " + taskIndex);
4064                    return;
4065                } else {
4066                    // More complicated: need to keep all affiliated tasks together.
4067                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4068                        // All went well.
4069                        return;
4070                    }
4071
4072                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4073                    // everything and then go through our general path of adding a new task.
4074                    needAffiliationFix = true;
4075                }
4076            } else {
4077                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4078                needAffiliationFix = true;
4079            }
4080        }
4081
4082        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4083        trimRecentsForTaskLocked(task, true);
4084
4085        N = mRecentTasks.size();
4086        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4087            final TaskRecord tr = mRecentTasks.remove(N - 1);
4088            tr.removedFromRecents();
4089            N--;
4090        }
4091        task.inRecents = true;
4092        if (!isAffiliated || needAffiliationFix) {
4093            // If this is a simple non-affiliated task, or we had some failure trying to
4094            // handle it as part of an affilated task, then just place it at the top.
4095            mRecentTasks.add(0, task);
4096        } else if (isAffiliated) {
4097            // If this is a new affiliated task, then move all of the affiliated tasks
4098            // to the front and insert this new one.
4099            TaskRecord other = task.mNextAffiliate;
4100            if (other == null) {
4101                other = task.mPrevAffiliate;
4102            }
4103            if (other != null) {
4104                int otherIndex = mRecentTasks.indexOf(other);
4105                if (otherIndex >= 0) {
4106                    // Insert new task at appropriate location.
4107                    int taskIndex;
4108                    if (other == task.mNextAffiliate) {
4109                        // We found the index of our next affiliation, which is who is
4110                        // before us in the list, so add after that point.
4111                        taskIndex = otherIndex+1;
4112                    } else {
4113                        // We found the index of our previous affiliation, which is who is
4114                        // after us in the list, so add at their position.
4115                        taskIndex = otherIndex;
4116                    }
4117                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4118                            + taskIndex + ": " + task);
4119                    mRecentTasks.add(taskIndex, task);
4120
4121                    // Now move everything to the front.
4122                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4123                        // All went well.
4124                        return;
4125                    }
4126
4127                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4128                    // everything and then go through our general path of adding a new task.
4129                    needAffiliationFix = true;
4130                } else {
4131                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4132                            + other);
4133                    needAffiliationFix = true;
4134                }
4135            } else {
4136                if (DEBUG_RECENTS) Slog.d(TAG,
4137                        "addRecent: adding affiliated task without next/prev:" + task);
4138                needAffiliationFix = true;
4139            }
4140        }
4141        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4142
4143        if (needAffiliationFix) {
4144            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4145            cleanupRecentTasksLocked(task.userId);
4146        }
4147    }
4148
4149    /**
4150     * If needed, remove oldest existing entries in recents that are for the same kind
4151     * of task as the given one.
4152     */
4153    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4154        int N = mRecentTasks.size();
4155        final Intent intent = task.intent;
4156        final boolean document = intent != null && intent.isDocument();
4157
4158        int maxRecents = task.maxRecents - 1;
4159        for (int i=0; i<N; i++) {
4160            final TaskRecord tr = mRecentTasks.get(i);
4161            if (task != tr) {
4162                if (task.userId != tr.userId) {
4163                    continue;
4164                }
4165                if (i > MAX_RECENT_BITMAPS) {
4166                    tr.freeLastThumbnail();
4167                }
4168                final Intent trIntent = tr.intent;
4169                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4170                    (intent == null || !intent.filterEquals(trIntent))) {
4171                    continue;
4172                }
4173                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4174                if (document && trIsDocument) {
4175                    // These are the same document activity (not necessarily the same doc).
4176                    if (maxRecents > 0) {
4177                        --maxRecents;
4178                        continue;
4179                    }
4180                    // Hit the maximum number of documents for this task. Fall through
4181                    // and remove this document from recents.
4182                } else if (document || trIsDocument) {
4183                    // Only one of these is a document. Not the droid we're looking for.
4184                    continue;
4185                }
4186            }
4187
4188            if (!doTrim) {
4189                // If the caller is not actually asking for a trim, just tell them we reached
4190                // a point where the trim would happen.
4191                return i;
4192            }
4193
4194            // Either task and tr are the same or, their affinities match or their intents match
4195            // and neither of them is a document, or they are documents using the same activity
4196            // and their maxRecents has been reached.
4197            tr.disposeThumbnail();
4198            mRecentTasks.remove(i);
4199            if (task != tr) {
4200                tr.removedFromRecents();
4201            }
4202            i--;
4203            N--;
4204            if (task.intent == null) {
4205                // If the new recent task we are adding is not fully
4206                // specified, then replace it with the existing recent task.
4207                task = tr;
4208            }
4209            notifyTaskPersisterLocked(tr, false);
4210        }
4211
4212        return -1;
4213    }
4214
4215    @Override
4216    public void reportActivityFullyDrawn(IBinder token) {
4217        synchronized (this) {
4218            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219            if (r == null) {
4220                return;
4221            }
4222            r.reportFullyDrawnLocked();
4223        }
4224    }
4225
4226    @Override
4227    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4228        synchronized (this) {
4229            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4230            if (r == null) {
4231                return;
4232            }
4233            final long origId = Binder.clearCallingIdentity();
4234            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4235            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4236                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4237            if (config != null) {
4238                r.frozenBeforeDestroy = true;
4239                if (!updateConfigurationLocked(config, r, false, false)) {
4240                    mStackSupervisor.resumeTopActivitiesLocked();
4241                }
4242            }
4243            Binder.restoreCallingIdentity(origId);
4244        }
4245    }
4246
4247    @Override
4248    public int getRequestedOrientation(IBinder token) {
4249        synchronized (this) {
4250            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4251            if (r == null) {
4252                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4253            }
4254            return mWindowManager.getAppOrientation(r.appToken);
4255        }
4256    }
4257
4258    /**
4259     * This is the internal entry point for handling Activity.finish().
4260     *
4261     * @param token The Binder token referencing the Activity we want to finish.
4262     * @param resultCode Result code, if any, from this Activity.
4263     * @param resultData Result data (Intent), if any, from this Activity.
4264     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4265     *            the root Activity in the task.
4266     *
4267     * @return Returns true if the activity successfully finished, or false if it is still running.
4268     */
4269    @Override
4270    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4271            boolean finishTask) {
4272        // Refuse possible leaked file descriptors
4273        if (resultData != null && resultData.hasFileDescriptors() == true) {
4274            throw new IllegalArgumentException("File descriptors passed in Intent");
4275        }
4276
4277        synchronized(this) {
4278            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4279            if (r == null) {
4280                return true;
4281            }
4282            // Keep track of the root activity of the task before we finish it
4283            TaskRecord tr = r.task;
4284            ActivityRecord rootR = tr.getRootActivity();
4285            if (rootR == null) {
4286                Slog.w(TAG, "Finishing task with all activities already finished");
4287            }
4288            // Do not allow task to finish in Lock Task mode.
4289            if (tr == mStackSupervisor.mLockTaskModeTask) {
4290                if (rootR == r) {
4291                    Slog.i(TAG, "Not finishing task in lock task mode");
4292                    mStackSupervisor.showLockTaskToast();
4293                    return false;
4294                }
4295            }
4296            if (mController != null) {
4297                // Find the first activity that is not finishing.
4298                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4299                if (next != null) {
4300                    // ask watcher if this is allowed
4301                    boolean resumeOK = true;
4302                    try {
4303                        resumeOK = mController.activityResuming(next.packageName);
4304                    } catch (RemoteException e) {
4305                        mController = null;
4306                        Watchdog.getInstance().setActivityController(null);
4307                    }
4308
4309                    if (!resumeOK) {
4310                        Slog.i(TAG, "Not finishing activity because controller resumed");
4311                        return false;
4312                    }
4313                }
4314            }
4315            final long origId = Binder.clearCallingIdentity();
4316            try {
4317                boolean res;
4318                if (finishTask && r == rootR) {
4319                    // If requested, remove the task that is associated to this activity only if it
4320                    // was the root activity in the task. The result code and data is ignored
4321                    // because we don't support returning them across task boundaries.
4322                    res = removeTaskByIdLocked(tr.taskId, false);
4323                    if (!res) {
4324                        Slog.i(TAG, "Removing task failed to finish activity");
4325                    }
4326                } else {
4327                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4328                            resultData, "app-request", true);
4329                    if (!res) {
4330                        Slog.i(TAG, "Failed to finish by app-request");
4331                    }
4332                }
4333                return res;
4334            } finally {
4335                Binder.restoreCallingIdentity(origId);
4336            }
4337        }
4338    }
4339
4340    @Override
4341    public final void finishHeavyWeightApp() {
4342        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351
4352        synchronized(this) {
4353            if (mHeavyWeightProcess == null) {
4354                return;
4355            }
4356
4357            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4358                    mHeavyWeightProcess.activities);
4359            for (int i=0; i<activities.size(); i++) {
4360                ActivityRecord r = activities.get(i);
4361                if (!r.finishing) {
4362                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4363                            null, "finish-heavy", true);
4364                }
4365            }
4366
4367            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4368                    mHeavyWeightProcess.userId, 0));
4369            mHeavyWeightProcess = null;
4370        }
4371    }
4372
4373    @Override
4374    public void crashApplication(int uid, int initialPid, String packageName,
4375            String message) {
4376        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4377                != PackageManager.PERMISSION_GRANTED) {
4378            String msg = "Permission Denial: crashApplication() from pid="
4379                    + Binder.getCallingPid()
4380                    + ", uid=" + Binder.getCallingUid()
4381                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4382            Slog.w(TAG, msg);
4383            throw new SecurityException(msg);
4384        }
4385
4386        synchronized(this) {
4387            ProcessRecord proc = null;
4388
4389            // Figure out which process to kill.  We don't trust that initialPid
4390            // still has any relation to current pids, so must scan through the
4391            // list.
4392            synchronized (mPidsSelfLocked) {
4393                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4394                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4395                    if (p.uid != uid) {
4396                        continue;
4397                    }
4398                    if (p.pid == initialPid) {
4399                        proc = p;
4400                        break;
4401                    }
4402                    if (p.pkgList.containsKey(packageName)) {
4403                        proc = p;
4404                    }
4405                }
4406            }
4407
4408            if (proc == null) {
4409                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4410                        + " initialPid=" + initialPid
4411                        + " packageName=" + packageName);
4412                return;
4413            }
4414
4415            if (proc.thread != null) {
4416                if (proc.pid == Process.myPid()) {
4417                    Log.w(TAG, "crashApplication: trying to crash self!");
4418                    return;
4419                }
4420                long ident = Binder.clearCallingIdentity();
4421                try {
4422                    proc.thread.scheduleCrash(message);
4423                } catch (RemoteException e) {
4424                }
4425                Binder.restoreCallingIdentity(ident);
4426            }
4427        }
4428    }
4429
4430    @Override
4431    public final void finishSubActivity(IBinder token, String resultWho,
4432            int requestCode) {
4433        synchronized(this) {
4434            final long origId = Binder.clearCallingIdentity();
4435            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4436            if (r != null) {
4437                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4438            }
4439            Binder.restoreCallingIdentity(origId);
4440        }
4441    }
4442
4443    @Override
4444    public boolean finishActivityAffinity(IBinder token) {
4445        synchronized(this) {
4446            final long origId = Binder.clearCallingIdentity();
4447            try {
4448                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4449
4450                ActivityRecord rootR = r.task.getRootActivity();
4451                // Do not allow task to finish in Lock Task mode.
4452                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4453                    if (rootR == r) {
4454                        mStackSupervisor.showLockTaskToast();
4455                        return false;
4456                    }
4457                }
4458                boolean res = false;
4459                if (r != null) {
4460                    res = r.task.stack.finishActivityAffinityLocked(r);
4461                }
4462                return res;
4463            } finally {
4464                Binder.restoreCallingIdentity(origId);
4465            }
4466        }
4467    }
4468
4469    @Override
4470    public void finishVoiceTask(IVoiceInteractionSession session) {
4471        synchronized(this) {
4472            final long origId = Binder.clearCallingIdentity();
4473            try {
4474                mStackSupervisor.finishVoiceTask(session);
4475            } finally {
4476                Binder.restoreCallingIdentity(origId);
4477            }
4478        }
4479
4480    }
4481
4482    @Override
4483    public boolean releaseActivityInstance(IBinder token) {
4484        synchronized(this) {
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4488                if (r.task == null || r.task.stack == null) {
4489                    return false;
4490                }
4491                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4492            } finally {
4493                Binder.restoreCallingIdentity(origId);
4494            }
4495        }
4496    }
4497
4498    @Override
4499    public void releaseSomeActivities(IApplicationThread appInt) {
4500        synchronized(this) {
4501            final long origId = Binder.clearCallingIdentity();
4502            try {
4503                ProcessRecord app = getRecordForAppLocked(appInt);
4504                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4505            } finally {
4506                Binder.restoreCallingIdentity(origId);
4507            }
4508        }
4509    }
4510
4511    @Override
4512    public boolean willActivityBeVisible(IBinder token) {
4513        synchronized(this) {
4514            ActivityStack stack = ActivityRecord.getStackLocked(token);
4515            if (stack != null) {
4516                return stack.willActivityBeVisibleLocked(token);
4517            }
4518            return false;
4519        }
4520    }
4521
4522    @Override
4523    public void overridePendingTransition(IBinder token, String packageName,
4524            int enterAnim, int exitAnim) {
4525        synchronized(this) {
4526            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4527            if (self == null) {
4528                return;
4529            }
4530
4531            final long origId = Binder.clearCallingIdentity();
4532
4533            if (self.state == ActivityState.RESUMED
4534                    || self.state == ActivityState.PAUSING) {
4535                mWindowManager.overridePendingAppTransition(packageName,
4536                        enterAnim, exitAnim, null);
4537            }
4538
4539            Binder.restoreCallingIdentity(origId);
4540        }
4541    }
4542
4543    /**
4544     * Main function for removing an existing process from the activity manager
4545     * as a result of that process going away.  Clears out all connections
4546     * to the process.
4547     */
4548    private final void handleAppDiedLocked(ProcessRecord app,
4549            boolean restarting, boolean allowRestart) {
4550        int pid = app.pid;
4551        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4552        if (!kept && !restarting) {
4553            removeLruProcessLocked(app);
4554            if (pid > 0) {
4555                ProcessList.remove(pid);
4556            }
4557        }
4558
4559        if (mProfileProc == app) {
4560            clearProfilerLocked();
4561        }
4562
4563        // Remove this application's activities from active lists.
4564        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4565
4566        app.activities.clear();
4567
4568        if (app.instrumentationClass != null) {
4569            Slog.w(TAG, "Crash of app " + app.processName
4570                  + " running instrumentation " + app.instrumentationClass);
4571            Bundle info = new Bundle();
4572            info.putString("shortMsg", "Process crashed.");
4573            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4574        }
4575
4576        if (!restarting) {
4577            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4578                // If there was nothing to resume, and we are not already
4579                // restarting this process, but there is a visible activity that
4580                // is hosted by the process...  then make sure all visible
4581                // activities are running, taking care of restarting this
4582                // process.
4583                if (hasVisibleActivities) {
4584                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4585                }
4586            }
4587        }
4588    }
4589
4590    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4591        IBinder threadBinder = thread.asBinder();
4592        // Find the application record.
4593        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4594            ProcessRecord rec = mLruProcesses.get(i);
4595            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4596                return i;
4597            }
4598        }
4599        return -1;
4600    }
4601
4602    final ProcessRecord getRecordForAppLocked(
4603            IApplicationThread thread) {
4604        if (thread == null) {
4605            return null;
4606        }
4607
4608        int appIndex = getLRURecordIndexForAppLocked(thread);
4609        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4610    }
4611
4612    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4613        // If there are no longer any background processes running,
4614        // and the app that died was not running instrumentation,
4615        // then tell everyone we are now low on memory.
4616        boolean haveBg = false;
4617        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4618            ProcessRecord rec = mLruProcesses.get(i);
4619            if (rec.thread != null
4620                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4621                haveBg = true;
4622                break;
4623            }
4624        }
4625
4626        if (!haveBg) {
4627            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4628            if (doReport) {
4629                long now = SystemClock.uptimeMillis();
4630                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4631                    doReport = false;
4632                } else {
4633                    mLastMemUsageReportTime = now;
4634                }
4635            }
4636            final ArrayList<ProcessMemInfo> memInfos
4637                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4638            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4639            long now = SystemClock.uptimeMillis();
4640            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4641                ProcessRecord rec = mLruProcesses.get(i);
4642                if (rec == dyingProc || rec.thread == null) {
4643                    continue;
4644                }
4645                if (doReport) {
4646                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4647                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4648                }
4649                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4650                    // The low memory report is overriding any current
4651                    // state for a GC request.  Make sure to do
4652                    // heavy/important/visible/foreground processes first.
4653                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4654                        rec.lastRequestedGc = 0;
4655                    } else {
4656                        rec.lastRequestedGc = rec.lastLowMemory;
4657                    }
4658                    rec.reportLowMemory = true;
4659                    rec.lastLowMemory = now;
4660                    mProcessesToGc.remove(rec);
4661                    addProcessToGcListLocked(rec);
4662                }
4663            }
4664            if (doReport) {
4665                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4666                mHandler.sendMessage(msg);
4667            }
4668            scheduleAppGcsLocked();
4669        }
4670    }
4671
4672    final void appDiedLocked(ProcessRecord app) {
4673       appDiedLocked(app, app.pid, app.thread);
4674    }
4675
4676    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4677        // First check if this ProcessRecord is actually active for the pid.
4678        synchronized (mPidsSelfLocked) {
4679            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4680            if (curProc != app) {
4681                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4682                return;
4683            }
4684        }
4685
4686        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4687        synchronized (stats) {
4688            stats.noteProcessDiedLocked(app.info.uid, pid);
4689        }
4690
4691        if (!app.killed) {
4692            Process.killProcessQuiet(pid);
4693            Process.killProcessGroup(app.info.uid, pid);
4694            app.killed = true;
4695        }
4696
4697        // Clean up already done if the process has been re-started.
4698        if (app.pid == pid && app.thread != null &&
4699                app.thread.asBinder() == thread.asBinder()) {
4700            boolean doLowMem = app.instrumentationClass == null;
4701            boolean doOomAdj = doLowMem;
4702            if (!app.killedByAm) {
4703                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4704                        + ") has died");
4705                mAllowLowerMemLevel = true;
4706            } else {
4707                // Note that we always want to do oom adj to update our state with the
4708                // new number of procs.
4709                mAllowLowerMemLevel = false;
4710                doLowMem = false;
4711            }
4712            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4713            if (DEBUG_CLEANUP) Slog.v(
4714                TAG, "Dying app: " + app + ", pid: " + pid
4715                + ", thread: " + thread.asBinder());
4716            handleAppDiedLocked(app, false, true);
4717
4718            if (doOomAdj) {
4719                updateOomAdjLocked();
4720            }
4721            if (doLowMem) {
4722                doLowMemReportIfNeededLocked(app);
4723            }
4724        } else if (app.pid != pid) {
4725            // A new process has already been started.
4726            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727                    + ") has died and restarted (pid " + app.pid + ").");
4728            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4729        } else if (DEBUG_PROCESSES) {
4730            Slog.d(TAG, "Received spurious death notification for thread "
4731                    + thread.asBinder());
4732        }
4733    }
4734
4735    /**
4736     * If a stack trace dump file is configured, dump process stack traces.
4737     * @param clearTraces causes the dump file to be erased prior to the new
4738     *    traces being written, if true; when false, the new traces will be
4739     *    appended to any existing file content.
4740     * @param firstPids of dalvik VM processes to dump stack traces for first
4741     * @param lastPids of dalvik VM processes to dump stack traces for last
4742     * @param nativeProcs optional list of native process names to dump stack crawls
4743     * @return file containing stack traces, or null if no dump file is configured
4744     */
4745    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4746            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4747        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4748        if (tracesPath == null || tracesPath.length() == 0) {
4749            return null;
4750        }
4751
4752        File tracesFile = new File(tracesPath);
4753        try {
4754            File tracesDir = tracesFile.getParentFile();
4755            if (!tracesDir.exists()) {
4756                tracesDir.mkdirs();
4757                if (!SELinux.restorecon(tracesDir)) {
4758                    return null;
4759                }
4760            }
4761            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4762
4763            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4764            tracesFile.createNewFile();
4765            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4766        } catch (IOException e) {
4767            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4768            return null;
4769        }
4770
4771        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4772        return tracesFile;
4773    }
4774
4775    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4776            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4777        // Use a FileObserver to detect when traces finish writing.
4778        // The order of traces is considered important to maintain for legibility.
4779        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4780            @Override
4781            public synchronized void onEvent(int event, String path) { notify(); }
4782        };
4783
4784        try {
4785            observer.startWatching();
4786
4787            // First collect all of the stacks of the most important pids.
4788            if (firstPids != null) {
4789                try {
4790                    int num = firstPids.size();
4791                    for (int i = 0; i < num; i++) {
4792                        synchronized (observer) {
4793                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4794                            observer.wait(200);  // Wait for write-close, give up after 200msec
4795                        }
4796                    }
4797                } catch (InterruptedException e) {
4798                    Slog.wtf(TAG, e);
4799                }
4800            }
4801
4802            // Next collect the stacks of the native pids
4803            if (nativeProcs != null) {
4804                int[] pids = Process.getPidsForCommands(nativeProcs);
4805                if (pids != null) {
4806                    for (int pid : pids) {
4807                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4808                    }
4809                }
4810            }
4811
4812            // Lastly, measure CPU usage.
4813            if (processCpuTracker != null) {
4814                processCpuTracker.init();
4815                System.gc();
4816                processCpuTracker.update();
4817                try {
4818                    synchronized (processCpuTracker) {
4819                        processCpuTracker.wait(500); // measure over 1/2 second.
4820                    }
4821                } catch (InterruptedException e) {
4822                }
4823                processCpuTracker.update();
4824
4825                // We'll take the stack crawls of just the top apps using CPU.
4826                final int N = processCpuTracker.countWorkingStats();
4827                int numProcs = 0;
4828                for (int i=0; i<N && numProcs<5; i++) {
4829                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4830                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4831                        numProcs++;
4832                        try {
4833                            synchronized (observer) {
4834                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4835                                observer.wait(200);  // Wait for write-close, give up after 200msec
4836                            }
4837                        } catch (InterruptedException e) {
4838                            Slog.wtf(TAG, e);
4839                        }
4840
4841                    }
4842                }
4843            }
4844        } finally {
4845            observer.stopWatching();
4846        }
4847    }
4848
4849    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4850        if (true || IS_USER_BUILD) {
4851            return;
4852        }
4853        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4854        if (tracesPath == null || tracesPath.length() == 0) {
4855            return;
4856        }
4857
4858        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4859        StrictMode.allowThreadDiskWrites();
4860        try {
4861            final File tracesFile = new File(tracesPath);
4862            final File tracesDir = tracesFile.getParentFile();
4863            final File tracesTmp = new File(tracesDir, "__tmp__");
4864            try {
4865                if (!tracesDir.exists()) {
4866                    tracesDir.mkdirs();
4867                    if (!SELinux.restorecon(tracesDir.getPath())) {
4868                        return;
4869                    }
4870                }
4871                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4872
4873                if (tracesFile.exists()) {
4874                    tracesTmp.delete();
4875                    tracesFile.renameTo(tracesTmp);
4876                }
4877                StringBuilder sb = new StringBuilder();
4878                Time tobj = new Time();
4879                tobj.set(System.currentTimeMillis());
4880                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4881                sb.append(": ");
4882                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4883                sb.append(" since ");
4884                sb.append(msg);
4885                FileOutputStream fos = new FileOutputStream(tracesFile);
4886                fos.write(sb.toString().getBytes());
4887                if (app == null) {
4888                    fos.write("\n*** No application process!".getBytes());
4889                }
4890                fos.close();
4891                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4892            } catch (IOException e) {
4893                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4894                return;
4895            }
4896
4897            if (app != null) {
4898                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4899                firstPids.add(app.pid);
4900                dumpStackTraces(tracesPath, firstPids, null, null, null);
4901            }
4902
4903            File lastTracesFile = null;
4904            File curTracesFile = null;
4905            for (int i=9; i>=0; i--) {
4906                String name = String.format(Locale.US, "slow%02d.txt", i);
4907                curTracesFile = new File(tracesDir, name);
4908                if (curTracesFile.exists()) {
4909                    if (lastTracesFile != null) {
4910                        curTracesFile.renameTo(lastTracesFile);
4911                    } else {
4912                        curTracesFile.delete();
4913                    }
4914                }
4915                lastTracesFile = curTracesFile;
4916            }
4917            tracesFile.renameTo(curTracesFile);
4918            if (tracesTmp.exists()) {
4919                tracesTmp.renameTo(tracesFile);
4920            }
4921        } finally {
4922            StrictMode.setThreadPolicy(oldPolicy);
4923        }
4924    }
4925
4926    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4927            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4928        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4929        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4930
4931        if (mController != null) {
4932            try {
4933                // 0 == continue, -1 = kill process immediately
4934                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4935                if (res < 0 && app.pid != MY_PID) {
4936                    app.kill("anr", true);
4937                }
4938            } catch (RemoteException e) {
4939                mController = null;
4940                Watchdog.getInstance().setActivityController(null);
4941            }
4942        }
4943
4944        long anrTime = SystemClock.uptimeMillis();
4945        if (MONITOR_CPU_USAGE) {
4946            updateCpuStatsNow();
4947        }
4948
4949        synchronized (this) {
4950            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4951            if (mShuttingDown) {
4952                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4953                return;
4954            } else if (app.notResponding) {
4955                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4956                return;
4957            } else if (app.crashing) {
4958                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4959                return;
4960            }
4961
4962            // In case we come through here for the same app before completing
4963            // this one, mark as anring now so we will bail out.
4964            app.notResponding = true;
4965
4966            // Log the ANR to the event log.
4967            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4968                    app.processName, app.info.flags, annotation);
4969
4970            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4971            firstPids.add(app.pid);
4972
4973            int parentPid = app.pid;
4974            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4975            if (parentPid != app.pid) firstPids.add(parentPid);
4976
4977            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4978
4979            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4980                ProcessRecord r = mLruProcesses.get(i);
4981                if (r != null && r.thread != null) {
4982                    int pid = r.pid;
4983                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4984                        if (r.persistent) {
4985                            firstPids.add(pid);
4986                        } else {
4987                            lastPids.put(pid, Boolean.TRUE);
4988                        }
4989                    }
4990                }
4991            }
4992        }
4993
4994        // Log the ANR to the main log.
4995        StringBuilder info = new StringBuilder();
4996        info.setLength(0);
4997        info.append("ANR in ").append(app.processName);
4998        if (activity != null && activity.shortComponentName != null) {
4999            info.append(" (").append(activity.shortComponentName).append(")");
5000        }
5001        info.append("\n");
5002        info.append("PID: ").append(app.pid).append("\n");
5003        if (annotation != null) {
5004            info.append("Reason: ").append(annotation).append("\n");
5005        }
5006        if (parent != null && parent != activity) {
5007            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5008        }
5009
5010        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5011
5012        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5013                NATIVE_STACKS_OF_INTEREST);
5014
5015        String cpuInfo = null;
5016        if (MONITOR_CPU_USAGE) {
5017            updateCpuStatsNow();
5018            synchronized (mProcessCpuTracker) {
5019                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5020            }
5021            info.append(processCpuTracker.printCurrentLoad());
5022            info.append(cpuInfo);
5023        }
5024
5025        info.append(processCpuTracker.printCurrentState(anrTime));
5026
5027        Slog.e(TAG, info.toString());
5028        if (tracesFile == null) {
5029            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5030            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5031        }
5032
5033        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5034                cpuInfo, tracesFile, null);
5035
5036        if (mController != null) {
5037            try {
5038                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5039                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5040                if (res != 0) {
5041                    if (res < 0 && app.pid != MY_PID) {
5042                        app.kill("anr", true);
5043                    } else {
5044                        synchronized (this) {
5045                            mServices.scheduleServiceTimeoutLocked(app);
5046                        }
5047                    }
5048                    return;
5049                }
5050            } catch (RemoteException e) {
5051                mController = null;
5052                Watchdog.getInstance().setActivityController(null);
5053            }
5054        }
5055
5056        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5057        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5058                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5059
5060        synchronized (this) {
5061            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5062
5063            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5064                app.kill("bg anr", true);
5065                return;
5066            }
5067
5068            // Set the app's notResponding state, and look up the errorReportReceiver
5069            makeAppNotRespondingLocked(app,
5070                    activity != null ? activity.shortComponentName : null,
5071                    annotation != null ? "ANR " + annotation : "ANR",
5072                    info.toString());
5073
5074            // Bring up the infamous App Not Responding dialog
5075            Message msg = Message.obtain();
5076            HashMap<String, Object> map = new HashMap<String, Object>();
5077            msg.what = SHOW_NOT_RESPONDING_MSG;
5078            msg.obj = map;
5079            msg.arg1 = aboveSystem ? 1 : 0;
5080            map.put("app", app);
5081            if (activity != null) {
5082                map.put("activity", activity);
5083            }
5084
5085            mHandler.sendMessage(msg);
5086        }
5087    }
5088
5089    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5090        if (!mLaunchWarningShown) {
5091            mLaunchWarningShown = true;
5092            mHandler.post(new Runnable() {
5093                @Override
5094                public void run() {
5095                    synchronized (ActivityManagerService.this) {
5096                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5097                        d.show();
5098                        mHandler.postDelayed(new Runnable() {
5099                            @Override
5100                            public void run() {
5101                                synchronized (ActivityManagerService.this) {
5102                                    d.dismiss();
5103                                    mLaunchWarningShown = false;
5104                                }
5105                            }
5106                        }, 4000);
5107                    }
5108                }
5109            });
5110        }
5111    }
5112
5113    @Override
5114    public boolean clearApplicationUserData(final String packageName,
5115            final IPackageDataObserver observer, int userId) {
5116        enforceNotIsolatedCaller("clearApplicationUserData");
5117        int uid = Binder.getCallingUid();
5118        int pid = Binder.getCallingPid();
5119        userId = handleIncomingUser(pid, uid,
5120                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5121        long callingId = Binder.clearCallingIdentity();
5122        try {
5123            IPackageManager pm = AppGlobals.getPackageManager();
5124            int pkgUid = -1;
5125            synchronized(this) {
5126                try {
5127                    pkgUid = pm.getPackageUid(packageName, userId);
5128                } catch (RemoteException e) {
5129                }
5130                if (pkgUid == -1) {
5131                    Slog.w(TAG, "Invalid packageName: " + packageName);
5132                    if (observer != null) {
5133                        try {
5134                            observer.onRemoveCompleted(packageName, false);
5135                        } catch (RemoteException e) {
5136                            Slog.i(TAG, "Observer no longer exists.");
5137                        }
5138                    }
5139                    return false;
5140                }
5141                if (uid == pkgUid || checkComponentPermission(
5142                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5143                        pid, uid, -1, true)
5144                        == PackageManager.PERMISSION_GRANTED) {
5145                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5146                } else {
5147                    throw new SecurityException("PID " + pid + " does not have permission "
5148                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5149                                    + " of package " + packageName);
5150                }
5151
5152                // Remove all tasks match the cleared application package and user
5153                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5154                    final TaskRecord tr = mRecentTasks.get(i);
5155                    final String taskPackageName =
5156                            tr.getBaseIntent().getComponent().getPackageName();
5157                    if (tr.userId != userId) continue;
5158                    if (!taskPackageName.equals(packageName)) continue;
5159                    removeTaskByIdLocked(tr.taskId, false);
5160                }
5161            }
5162
5163            try {
5164                // Clear application user data
5165                pm.clearApplicationUserData(packageName, observer, userId);
5166
5167                synchronized(this) {
5168                    // Remove all permissions granted from/to this package
5169                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5170                }
5171
5172                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5173                        Uri.fromParts("package", packageName, null));
5174                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5175                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5176                        null, null, 0, null, null, null, false, false, userId);
5177            } catch (RemoteException e) {
5178            }
5179        } finally {
5180            Binder.restoreCallingIdentity(callingId);
5181        }
5182        return true;
5183    }
5184
5185    @Override
5186    public void killBackgroundProcesses(final String packageName, int userId) {
5187        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5188                != PackageManager.PERMISSION_GRANTED &&
5189                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5190                        != PackageManager.PERMISSION_GRANTED) {
5191            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5192                    + Binder.getCallingPid()
5193                    + ", uid=" + Binder.getCallingUid()
5194                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5195            Slog.w(TAG, msg);
5196            throw new SecurityException(msg);
5197        }
5198
5199        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5200                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            IPackageManager pm = AppGlobals.getPackageManager();
5204            synchronized(this) {
5205                int appId = -1;
5206                try {
5207                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5208                } catch (RemoteException e) {
5209                }
5210                if (appId == -1) {
5211                    Slog.w(TAG, "Invalid packageName: " + packageName);
5212                    return;
5213                }
5214                killPackageProcessesLocked(packageName, appId, userId,
5215                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5216            }
5217        } finally {
5218            Binder.restoreCallingIdentity(callingId);
5219        }
5220    }
5221
5222    @Override
5223    public void killAllBackgroundProcesses() {
5224        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5225                != PackageManager.PERMISSION_GRANTED) {
5226            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5227                    + Binder.getCallingPid()
5228                    + ", uid=" + Binder.getCallingUid()
5229                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5230            Slog.w(TAG, msg);
5231            throw new SecurityException(msg);
5232        }
5233
5234        long callingId = Binder.clearCallingIdentity();
5235        try {
5236            synchronized(this) {
5237                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5238                final int NP = mProcessNames.getMap().size();
5239                for (int ip=0; ip<NP; ip++) {
5240                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5241                    final int NA = apps.size();
5242                    for (int ia=0; ia<NA; ia++) {
5243                        ProcessRecord app = apps.valueAt(ia);
5244                        if (app.persistent) {
5245                            // we don't kill persistent processes
5246                            continue;
5247                        }
5248                        if (app.removed) {
5249                            procs.add(app);
5250                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5251                            app.removed = true;
5252                            procs.add(app);
5253                        }
5254                    }
5255                }
5256
5257                int N = procs.size();
5258                for (int i=0; i<N; i++) {
5259                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5260                }
5261                mAllowLowerMemLevel = true;
5262                updateOomAdjLocked();
5263                doLowMemReportIfNeededLocked(null);
5264            }
5265        } finally {
5266            Binder.restoreCallingIdentity(callingId);
5267        }
5268    }
5269
5270    @Override
5271    public void forceStopPackage(final String packageName, int userId) {
5272        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5273                != PackageManager.PERMISSION_GRANTED) {
5274            String msg = "Permission Denial: forceStopPackage() from pid="
5275                    + Binder.getCallingPid()
5276                    + ", uid=" + Binder.getCallingUid()
5277                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5278            Slog.w(TAG, msg);
5279            throw new SecurityException(msg);
5280        }
5281        final int callingPid = Binder.getCallingPid();
5282        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5283                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5284        long callingId = Binder.clearCallingIdentity();
5285        try {
5286            IPackageManager pm = AppGlobals.getPackageManager();
5287            synchronized(this) {
5288                int[] users = userId == UserHandle.USER_ALL
5289                        ? getUsersLocked() : new int[] { userId };
5290                for (int user : users) {
5291                    int pkgUid = -1;
5292                    try {
5293                        pkgUid = pm.getPackageUid(packageName, user);
5294                    } catch (RemoteException e) {
5295                    }
5296                    if (pkgUid == -1) {
5297                        Slog.w(TAG, "Invalid packageName: " + packageName);
5298                        continue;
5299                    }
5300                    try {
5301                        pm.setPackageStoppedState(packageName, true, user);
5302                    } catch (RemoteException e) {
5303                    } catch (IllegalArgumentException e) {
5304                        Slog.w(TAG, "Failed trying to unstop package "
5305                                + packageName + ": " + e);
5306                    }
5307                    if (isUserRunningLocked(user, false)) {
5308                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5309                    }
5310                }
5311            }
5312        } finally {
5313            Binder.restoreCallingIdentity(callingId);
5314        }
5315    }
5316
5317    @Override
5318    public void addPackageDependency(String packageName) {
5319        synchronized (this) {
5320            int callingPid = Binder.getCallingPid();
5321            if (callingPid == Process.myPid()) {
5322                //  Yeah, um, no.
5323                return;
5324            }
5325            ProcessRecord proc;
5326            synchronized (mPidsSelfLocked) {
5327                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5328            }
5329            if (proc != null) {
5330                if (proc.pkgDeps == null) {
5331                    proc.pkgDeps = new ArraySet<String>(1);
5332                }
5333                proc.pkgDeps.add(packageName);
5334            }
5335        }
5336    }
5337
5338    /*
5339     * The pkg name and app id have to be specified.
5340     */
5341    @Override
5342    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5343        if (pkg == null) {
5344            return;
5345        }
5346        // Make sure the uid is valid.
5347        if (appid < 0) {
5348            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5349            return;
5350        }
5351        int callerUid = Binder.getCallingUid();
5352        // Only the system server can kill an application
5353        if (callerUid == Process.SYSTEM_UID) {
5354            // Post an aysnc message to kill the application
5355            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5356            msg.arg1 = appid;
5357            msg.arg2 = 0;
5358            Bundle bundle = new Bundle();
5359            bundle.putString("pkg", pkg);
5360            bundle.putString("reason", reason);
5361            msg.obj = bundle;
5362            mHandler.sendMessage(msg);
5363        } else {
5364            throw new SecurityException(callerUid + " cannot kill pkg: " +
5365                    pkg);
5366        }
5367    }
5368
5369    @Override
5370    public void closeSystemDialogs(String reason) {
5371        enforceNotIsolatedCaller("closeSystemDialogs");
5372
5373        final int pid = Binder.getCallingPid();
5374        final int uid = Binder.getCallingUid();
5375        final long origId = Binder.clearCallingIdentity();
5376        try {
5377            synchronized (this) {
5378                // Only allow this from foreground processes, so that background
5379                // applications can't abuse it to prevent system UI from being shown.
5380                if (uid >= Process.FIRST_APPLICATION_UID) {
5381                    ProcessRecord proc;
5382                    synchronized (mPidsSelfLocked) {
5383                        proc = mPidsSelfLocked.get(pid);
5384                    }
5385                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5386                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5387                                + " from background process " + proc);
5388                        return;
5389                    }
5390                }
5391                closeSystemDialogsLocked(reason);
5392            }
5393        } finally {
5394            Binder.restoreCallingIdentity(origId);
5395        }
5396    }
5397
5398    void closeSystemDialogsLocked(String reason) {
5399        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5400        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5401                | Intent.FLAG_RECEIVER_FOREGROUND);
5402        if (reason != null) {
5403            intent.putExtra("reason", reason);
5404        }
5405        mWindowManager.closeSystemDialogs(reason);
5406
5407        mStackSupervisor.closeSystemDialogsLocked();
5408
5409        broadcastIntentLocked(null, null, intent, null,
5410                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5411                Process.SYSTEM_UID, UserHandle.USER_ALL);
5412    }
5413
5414    @Override
5415    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5416        enforceNotIsolatedCaller("getProcessMemoryInfo");
5417        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5418        for (int i=pids.length-1; i>=0; i--) {
5419            ProcessRecord proc;
5420            int oomAdj;
5421            synchronized (this) {
5422                synchronized (mPidsSelfLocked) {
5423                    proc = mPidsSelfLocked.get(pids[i]);
5424                    oomAdj = proc != null ? proc.setAdj : 0;
5425                }
5426            }
5427            infos[i] = new Debug.MemoryInfo();
5428            Debug.getMemoryInfo(pids[i], infos[i]);
5429            if (proc != null) {
5430                synchronized (this) {
5431                    if (proc.thread != null && proc.setAdj == oomAdj) {
5432                        // Record this for posterity if the process has been stable.
5433                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5434                                infos[i].getTotalUss(), false, proc.pkgList);
5435                    }
5436                }
5437            }
5438        }
5439        return infos;
5440    }
5441
5442    @Override
5443    public long[] getProcessPss(int[] pids) {
5444        enforceNotIsolatedCaller("getProcessPss");
5445        long[] pss = new long[pids.length];
5446        for (int i=pids.length-1; i>=0; i--) {
5447            ProcessRecord proc;
5448            int oomAdj;
5449            synchronized (this) {
5450                synchronized (mPidsSelfLocked) {
5451                    proc = mPidsSelfLocked.get(pids[i]);
5452                    oomAdj = proc != null ? proc.setAdj : 0;
5453                }
5454            }
5455            long[] tmpUss = new long[1];
5456            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5457            if (proc != null) {
5458                synchronized (this) {
5459                    if (proc.thread != null && proc.setAdj == oomAdj) {
5460                        // Record this for posterity if the process has been stable.
5461                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5462                    }
5463                }
5464            }
5465        }
5466        return pss;
5467    }
5468
5469    @Override
5470    public void killApplicationProcess(String processName, int uid) {
5471        if (processName == null) {
5472            return;
5473        }
5474
5475        int callerUid = Binder.getCallingUid();
5476        // Only the system server can kill an application
5477        if (callerUid == Process.SYSTEM_UID) {
5478            synchronized (this) {
5479                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5480                if (app != null && app.thread != null) {
5481                    try {
5482                        app.thread.scheduleSuicide();
5483                    } catch (RemoteException e) {
5484                        // If the other end already died, then our work here is done.
5485                    }
5486                } else {
5487                    Slog.w(TAG, "Process/uid not found attempting kill of "
5488                            + processName + " / " + uid);
5489                }
5490            }
5491        } else {
5492            throw new SecurityException(callerUid + " cannot kill app process: " +
5493                    processName);
5494        }
5495    }
5496
5497    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5498        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5499                false, true, false, false, UserHandle.getUserId(uid), reason);
5500        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5501                Uri.fromParts("package", packageName, null));
5502        if (!mProcessesReady) {
5503            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5504                    | Intent.FLAG_RECEIVER_FOREGROUND);
5505        }
5506        intent.putExtra(Intent.EXTRA_UID, uid);
5507        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5508        broadcastIntentLocked(null, null, intent,
5509                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5510                false, false,
5511                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5512    }
5513
5514    private void forceStopUserLocked(int userId, String reason) {
5515        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5516        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5517        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5518                | Intent.FLAG_RECEIVER_FOREGROUND);
5519        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5520        broadcastIntentLocked(null, null, intent,
5521                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5522                false, false,
5523                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5524    }
5525
5526    private final boolean killPackageProcessesLocked(String packageName, int appId,
5527            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5528            boolean doit, boolean evenPersistent, String reason) {
5529        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5530
5531        // Remove all processes this package may have touched: all with the
5532        // same UID (except for the system or root user), and all whose name
5533        // matches the package name.
5534        final int NP = mProcessNames.getMap().size();
5535        for (int ip=0; ip<NP; ip++) {
5536            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5537            final int NA = apps.size();
5538            for (int ia=0; ia<NA; ia++) {
5539                ProcessRecord app = apps.valueAt(ia);
5540                if (app.persistent && !evenPersistent) {
5541                    // we don't kill persistent processes
5542                    continue;
5543                }
5544                if (app.removed) {
5545                    if (doit) {
5546                        procs.add(app);
5547                    }
5548                    continue;
5549                }
5550
5551                // Skip process if it doesn't meet our oom adj requirement.
5552                if (app.setAdj < minOomAdj) {
5553                    continue;
5554                }
5555
5556                // If no package is specified, we call all processes under the
5557                // give user id.
5558                if (packageName == null) {
5559                    if (app.userId != userId) {
5560                        continue;
5561                    }
5562                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5563                        continue;
5564                    }
5565                // Package has been specified, we want to hit all processes
5566                // that match it.  We need to qualify this by the processes
5567                // that are running under the specified app and user ID.
5568                } else {
5569                    final boolean isDep = app.pkgDeps != null
5570                            && app.pkgDeps.contains(packageName);
5571                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5572                        continue;
5573                    }
5574                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5575                        continue;
5576                    }
5577                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5578                        continue;
5579                    }
5580                }
5581
5582                // Process has passed all conditions, kill it!
5583                if (!doit) {
5584                    return true;
5585                }
5586                app.removed = true;
5587                procs.add(app);
5588            }
5589        }
5590
5591        int N = procs.size();
5592        for (int i=0; i<N; i++) {
5593            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5594        }
5595        updateOomAdjLocked();
5596        return N > 0;
5597    }
5598
5599    private final boolean forceStopPackageLocked(String name, int appId,
5600            boolean callerWillRestart, boolean purgeCache, boolean doit,
5601            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5602        int i;
5603        int N;
5604
5605        if (userId == UserHandle.USER_ALL && name == null) {
5606            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5607        }
5608
5609        if (appId < 0 && name != null) {
5610            try {
5611                appId = UserHandle.getAppId(
5612                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5613            } catch (RemoteException e) {
5614            }
5615        }
5616
5617        if (doit) {
5618            if (name != null) {
5619                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5620                        + " user=" + userId + ": " + reason);
5621            } else {
5622                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5623            }
5624
5625            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5626            for (int ip=pmap.size()-1; ip>=0; ip--) {
5627                SparseArray<Long> ba = pmap.valueAt(ip);
5628                for (i=ba.size()-1; i>=0; i--) {
5629                    boolean remove = false;
5630                    final int entUid = ba.keyAt(i);
5631                    if (name != null) {
5632                        if (userId == UserHandle.USER_ALL) {
5633                            if (UserHandle.getAppId(entUid) == appId) {
5634                                remove = true;
5635                            }
5636                        } else {
5637                            if (entUid == UserHandle.getUid(userId, appId)) {
5638                                remove = true;
5639                            }
5640                        }
5641                    } else if (UserHandle.getUserId(entUid) == userId) {
5642                        remove = true;
5643                    }
5644                    if (remove) {
5645                        ba.removeAt(i);
5646                    }
5647                }
5648                if (ba.size() == 0) {
5649                    pmap.removeAt(ip);
5650                }
5651            }
5652        }
5653
5654        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5655                -100, callerWillRestart, true, doit, evenPersistent,
5656                name == null ? ("stop user " + userId) : ("stop " + name));
5657
5658        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5659            if (!doit) {
5660                return true;
5661            }
5662            didSomething = true;
5663        }
5664
5665        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5666            if (!doit) {
5667                return true;
5668            }
5669            didSomething = true;
5670        }
5671
5672        if (name == null) {
5673            // Remove all sticky broadcasts from this user.
5674            mStickyBroadcasts.remove(userId);
5675        }
5676
5677        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5678        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5679                userId, providers)) {
5680            if (!doit) {
5681                return true;
5682            }
5683            didSomething = true;
5684        }
5685        N = providers.size();
5686        for (i=0; i<N; i++) {
5687            removeDyingProviderLocked(null, providers.get(i), true);
5688        }
5689
5690        // Remove transient permissions granted from/to this package/user
5691        removeUriPermissionsForPackageLocked(name, userId, false);
5692
5693        if (name == null || uninstalling) {
5694            // Remove pending intents.  For now we only do this when force
5695            // stopping users, because we have some problems when doing this
5696            // for packages -- app widgets are not currently cleaned up for
5697            // such packages, so they can be left with bad pending intents.
5698            if (mIntentSenderRecords.size() > 0) {
5699                Iterator<WeakReference<PendingIntentRecord>> it
5700                        = mIntentSenderRecords.values().iterator();
5701                while (it.hasNext()) {
5702                    WeakReference<PendingIntentRecord> wpir = it.next();
5703                    if (wpir == null) {
5704                        it.remove();
5705                        continue;
5706                    }
5707                    PendingIntentRecord pir = wpir.get();
5708                    if (pir == null) {
5709                        it.remove();
5710                        continue;
5711                    }
5712                    if (name == null) {
5713                        // Stopping user, remove all objects for the user.
5714                        if (pir.key.userId != userId) {
5715                            // Not the same user, skip it.
5716                            continue;
5717                        }
5718                    } else {
5719                        if (UserHandle.getAppId(pir.uid) != appId) {
5720                            // Different app id, skip it.
5721                            continue;
5722                        }
5723                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5724                            // Different user, skip it.
5725                            continue;
5726                        }
5727                        if (!pir.key.packageName.equals(name)) {
5728                            // Different package, skip it.
5729                            continue;
5730                        }
5731                    }
5732                    if (!doit) {
5733                        return true;
5734                    }
5735                    didSomething = true;
5736                    it.remove();
5737                    pir.canceled = true;
5738                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5739                        pir.key.activity.pendingResults.remove(pir.ref);
5740                    }
5741                }
5742            }
5743        }
5744
5745        if (doit) {
5746            if (purgeCache && name != null) {
5747                AttributeCache ac = AttributeCache.instance();
5748                if (ac != null) {
5749                    ac.removePackage(name);
5750                }
5751            }
5752            if (mBooted) {
5753                mStackSupervisor.resumeTopActivitiesLocked();
5754                mStackSupervisor.scheduleIdleLocked();
5755            }
5756        }
5757
5758        return didSomething;
5759    }
5760
5761    private final boolean removeProcessLocked(ProcessRecord app,
5762            boolean callerWillRestart, boolean allowRestart, String reason) {
5763        final String name = app.processName;
5764        final int uid = app.uid;
5765        if (DEBUG_PROCESSES) Slog.d(
5766            TAG, "Force removing proc " + app.toShortString() + " (" + name
5767            + "/" + uid + ")");
5768
5769        mProcessNames.remove(name, uid);
5770        mIsolatedProcesses.remove(app.uid);
5771        if (mHeavyWeightProcess == app) {
5772            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5773                    mHeavyWeightProcess.userId, 0));
5774            mHeavyWeightProcess = null;
5775        }
5776        boolean needRestart = false;
5777        if (app.pid > 0 && app.pid != MY_PID) {
5778            int pid = app.pid;
5779            synchronized (mPidsSelfLocked) {
5780                mPidsSelfLocked.remove(pid);
5781                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5782            }
5783            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5784            if (app.isolated) {
5785                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5786            }
5787            app.kill(reason, true);
5788            handleAppDiedLocked(app, true, allowRestart);
5789            removeLruProcessLocked(app);
5790
5791            if (app.persistent && !app.isolated) {
5792                if (!callerWillRestart) {
5793                    addAppLocked(app.info, false, null /* ABI override */);
5794                } else {
5795                    needRestart = true;
5796                }
5797            }
5798        } else {
5799            mRemovedProcesses.add(app);
5800        }
5801
5802        return needRestart;
5803    }
5804
5805    private final void processStartTimedOutLocked(ProcessRecord app) {
5806        final int pid = app.pid;
5807        boolean gone = false;
5808        synchronized (mPidsSelfLocked) {
5809            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5810            if (knownApp != null && knownApp.thread == null) {
5811                mPidsSelfLocked.remove(pid);
5812                gone = true;
5813            }
5814        }
5815
5816        if (gone) {
5817            Slog.w(TAG, "Process " + app + " failed to attach");
5818            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5819                    pid, app.uid, app.processName);
5820            mProcessNames.remove(app.processName, app.uid);
5821            mIsolatedProcesses.remove(app.uid);
5822            if (mHeavyWeightProcess == app) {
5823                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5824                        mHeavyWeightProcess.userId, 0));
5825                mHeavyWeightProcess = null;
5826            }
5827            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5828            if (app.isolated) {
5829                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5830            }
5831            // Take care of any launching providers waiting for this process.
5832            checkAppInLaunchingProvidersLocked(app, true);
5833            // Take care of any services that are waiting for the process.
5834            mServices.processStartTimedOutLocked(app);
5835            app.kill("start timeout", true);
5836            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5837                Slog.w(TAG, "Unattached app died before backup, skipping");
5838                try {
5839                    IBackupManager bm = IBackupManager.Stub.asInterface(
5840                            ServiceManager.getService(Context.BACKUP_SERVICE));
5841                    bm.agentDisconnected(app.info.packageName);
5842                } catch (RemoteException e) {
5843                    // Can't happen; the backup manager is local
5844                }
5845            }
5846            if (isPendingBroadcastProcessLocked(pid)) {
5847                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5848                skipPendingBroadcastLocked(pid);
5849            }
5850        } else {
5851            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5852        }
5853    }
5854
5855    private final boolean attachApplicationLocked(IApplicationThread thread,
5856            int pid) {
5857
5858        // Find the application record that is being attached...  either via
5859        // the pid if we are running in multiple processes, or just pull the
5860        // next app record if we are emulating process with anonymous threads.
5861        ProcessRecord app;
5862        if (pid != MY_PID && pid >= 0) {
5863            synchronized (mPidsSelfLocked) {
5864                app = mPidsSelfLocked.get(pid);
5865            }
5866        } else {
5867            app = null;
5868        }
5869
5870        if (app == null) {
5871            Slog.w(TAG, "No pending application record for pid " + pid
5872                    + " (IApplicationThread " + thread + "); dropping process");
5873            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5874            if (pid > 0 && pid != MY_PID) {
5875                Process.killProcessQuiet(pid);
5876                //TODO: Process.killProcessGroup(app.info.uid, pid);
5877            } else {
5878                try {
5879                    thread.scheduleExit();
5880                } catch (Exception e) {
5881                    // Ignore exceptions.
5882                }
5883            }
5884            return false;
5885        }
5886
5887        // If this application record is still attached to a previous
5888        // process, clean it up now.
5889        if (app.thread != null) {
5890            handleAppDiedLocked(app, true, true);
5891        }
5892
5893        // Tell the process all about itself.
5894
5895        if (localLOGV) Slog.v(
5896                TAG, "Binding process pid " + pid + " to record " + app);
5897
5898        final String processName = app.processName;
5899        try {
5900            AppDeathRecipient adr = new AppDeathRecipient(
5901                    app, pid, thread);
5902            thread.asBinder().linkToDeath(adr, 0);
5903            app.deathRecipient = adr;
5904        } catch (RemoteException e) {
5905            app.resetPackageList(mProcessStats);
5906            startProcessLocked(app, "link fail", processName);
5907            return false;
5908        }
5909
5910        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5911
5912        app.makeActive(thread, mProcessStats);
5913        app.curAdj = app.setAdj = -100;
5914        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5915        app.forcingToForeground = null;
5916        updateProcessForegroundLocked(app, false, false);
5917        app.hasShownUi = false;
5918        app.debugging = false;
5919        app.cached = false;
5920        app.killedByAm = false;
5921
5922        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5923
5924        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5925        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5926
5927        if (!normalMode) {
5928            Slog.i(TAG, "Launching preboot mode app: " + app);
5929        }
5930
5931        if (localLOGV) Slog.v(
5932            TAG, "New app record " + app
5933            + " thread=" + thread.asBinder() + " pid=" + pid);
5934        try {
5935            int testMode = IApplicationThread.DEBUG_OFF;
5936            if (mDebugApp != null && mDebugApp.equals(processName)) {
5937                testMode = mWaitForDebugger
5938                    ? IApplicationThread.DEBUG_WAIT
5939                    : IApplicationThread.DEBUG_ON;
5940                app.debugging = true;
5941                if (mDebugTransient) {
5942                    mDebugApp = mOrigDebugApp;
5943                    mWaitForDebugger = mOrigWaitForDebugger;
5944                }
5945            }
5946            String profileFile = app.instrumentationProfileFile;
5947            ParcelFileDescriptor profileFd = null;
5948            int samplingInterval = 0;
5949            boolean profileAutoStop = false;
5950            if (mProfileApp != null && mProfileApp.equals(processName)) {
5951                mProfileProc = app;
5952                profileFile = mProfileFile;
5953                profileFd = mProfileFd;
5954                samplingInterval = mSamplingInterval;
5955                profileAutoStop = mAutoStopProfiler;
5956            }
5957            boolean enableOpenGlTrace = false;
5958            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5959                enableOpenGlTrace = true;
5960                mOpenGlTraceApp = null;
5961            }
5962
5963            // If the app is being launched for restore or full backup, set it up specially
5964            boolean isRestrictedBackupMode = false;
5965            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5966                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5967                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5968                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5969            }
5970
5971            ensurePackageDexOpt(app.instrumentationInfo != null
5972                    ? app.instrumentationInfo.packageName
5973                    : app.info.packageName);
5974            if (app.instrumentationClass != null) {
5975                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5976            }
5977            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5978                    + processName + " with config " + mConfiguration);
5979            ApplicationInfo appInfo = app.instrumentationInfo != null
5980                    ? app.instrumentationInfo : app.info;
5981            app.compat = compatibilityInfoForPackageLocked(appInfo);
5982            if (profileFd != null) {
5983                profileFd = profileFd.dup();
5984            }
5985            ProfilerInfo profilerInfo = profileFile == null ? null
5986                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5987            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5988                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5989                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5990                    isRestrictedBackupMode || !normalMode, app.persistent,
5991                    new Configuration(mConfiguration), app.compat,
5992                    getCommonServicesLocked(app.isolated),
5993                    mCoreSettingsObserver.getCoreSettingsLocked());
5994            updateLruProcessLocked(app, false, null);
5995            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5996        } catch (Exception e) {
5997            // todo: Yikes!  What should we do?  For now we will try to
5998            // start another process, but that could easily get us in
5999            // an infinite loop of restarting processes...
6000            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6001
6002            app.resetPackageList(mProcessStats);
6003            app.unlinkDeathRecipient();
6004            startProcessLocked(app, "bind fail", processName);
6005            return false;
6006        }
6007
6008        // Remove this record from the list of starting applications.
6009        mPersistentStartingProcesses.remove(app);
6010        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6011                "Attach application locked removing on hold: " + app);
6012        mProcessesOnHold.remove(app);
6013
6014        boolean badApp = false;
6015        boolean didSomething = false;
6016
6017        // See if the top visible activity is waiting to run in this process...
6018        if (normalMode) {
6019            try {
6020                if (mStackSupervisor.attachApplicationLocked(app)) {
6021                    didSomething = true;
6022                }
6023            } catch (Exception e) {
6024                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6025                badApp = true;
6026            }
6027        }
6028
6029        // Find any services that should be running in this process...
6030        if (!badApp) {
6031            try {
6032                didSomething |= mServices.attachApplicationLocked(app, processName);
6033            } catch (Exception e) {
6034                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6035                badApp = true;
6036            }
6037        }
6038
6039        // Check if a next-broadcast receiver is in this process...
6040        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6041            try {
6042                didSomething |= sendPendingBroadcastsLocked(app);
6043            } catch (Exception e) {
6044                // If the app died trying to launch the receiver we declare it 'bad'
6045                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6046                badApp = true;
6047            }
6048        }
6049
6050        // Check whether the next backup agent is in this process...
6051        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6052            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6053            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6054            try {
6055                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6056                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6057                        mBackupTarget.backupMode);
6058            } catch (Exception e) {
6059                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6060                badApp = true;
6061            }
6062        }
6063
6064        if (badApp) {
6065            app.kill("error during init", true);
6066            handleAppDiedLocked(app, false, true);
6067            return false;
6068        }
6069
6070        if (!didSomething) {
6071            updateOomAdjLocked();
6072        }
6073
6074        return true;
6075    }
6076
6077    @Override
6078    public final void attachApplication(IApplicationThread thread) {
6079        synchronized (this) {
6080            int callingPid = Binder.getCallingPid();
6081            final long origId = Binder.clearCallingIdentity();
6082            attachApplicationLocked(thread, callingPid);
6083            Binder.restoreCallingIdentity(origId);
6084        }
6085    }
6086
6087    @Override
6088    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6089        final long origId = Binder.clearCallingIdentity();
6090        synchronized (this) {
6091            ActivityStack stack = ActivityRecord.getStackLocked(token);
6092            if (stack != null) {
6093                ActivityRecord r =
6094                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6095                if (stopProfiling) {
6096                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6097                        try {
6098                            mProfileFd.close();
6099                        } catch (IOException e) {
6100                        }
6101                        clearProfilerLocked();
6102                    }
6103                }
6104            }
6105        }
6106        Binder.restoreCallingIdentity(origId);
6107    }
6108
6109    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6110        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6111                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6112    }
6113
6114    void enableScreenAfterBoot() {
6115        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6116                SystemClock.uptimeMillis());
6117        mWindowManager.enableScreenAfterBoot();
6118
6119        synchronized (this) {
6120            updateEventDispatchingLocked();
6121        }
6122    }
6123
6124    @Override
6125    public void showBootMessage(final CharSequence msg, final boolean always) {
6126        enforceNotIsolatedCaller("showBootMessage");
6127        mWindowManager.showBootMessage(msg, always);
6128    }
6129
6130    @Override
6131    public void keyguardWaitingForActivityDrawn() {
6132        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6133        final long token = Binder.clearCallingIdentity();
6134        try {
6135            synchronized (this) {
6136                if (DEBUG_LOCKSCREEN) logLockScreen("");
6137                mWindowManager.keyguardWaitingForActivityDrawn();
6138                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6139                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6140                    updateSleepIfNeededLocked();
6141                }
6142            }
6143        } finally {
6144            Binder.restoreCallingIdentity(token);
6145        }
6146    }
6147
6148    final void finishBooting() {
6149        synchronized (this) {
6150            if (!mBootAnimationComplete) {
6151                mCallFinishBooting = true;
6152                return;
6153            }
6154            mCallFinishBooting = false;
6155        }
6156
6157        ArraySet<String> completedIsas = new ArraySet<String>();
6158        for (String abi : Build.SUPPORTED_ABIS) {
6159            Process.establishZygoteConnectionForAbi(abi);
6160            final String instructionSet = VMRuntime.getInstructionSet(abi);
6161            if (!completedIsas.contains(instructionSet)) {
6162                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6163                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6164                }
6165                completedIsas.add(instructionSet);
6166            }
6167        }
6168
6169        IntentFilter pkgFilter = new IntentFilter();
6170        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6171        pkgFilter.addDataScheme("package");
6172        mContext.registerReceiver(new BroadcastReceiver() {
6173            @Override
6174            public void onReceive(Context context, Intent intent) {
6175                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6176                if (pkgs != null) {
6177                    for (String pkg : pkgs) {
6178                        synchronized (ActivityManagerService.this) {
6179                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6180                                    0, "finished booting")) {
6181                                setResultCode(Activity.RESULT_OK);
6182                                return;
6183                            }
6184                        }
6185                    }
6186                }
6187            }
6188        }, pkgFilter);
6189
6190        // Let system services know.
6191        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6192
6193        synchronized (this) {
6194            // Ensure that any processes we had put on hold are now started
6195            // up.
6196            final int NP = mProcessesOnHold.size();
6197            if (NP > 0) {
6198                ArrayList<ProcessRecord> procs =
6199                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6200                for (int ip=0; ip<NP; ip++) {
6201                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6202                            + procs.get(ip));
6203                    startProcessLocked(procs.get(ip), "on-hold", null);
6204                }
6205            }
6206
6207            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6208                // Start looking for apps that are abusing wake locks.
6209                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6210                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6211                // Tell anyone interested that we are done booting!
6212                SystemProperties.set("sys.boot_completed", "1");
6213
6214                // And trigger dev.bootcomplete if we are not showing encryption progress
6215                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6216                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6217                    SystemProperties.set("dev.bootcomplete", "1");
6218                }
6219                for (int i=0; i<mStartedUsers.size(); i++) {
6220                    UserStartedState uss = mStartedUsers.valueAt(i);
6221                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6222                        uss.mState = UserStartedState.STATE_RUNNING;
6223                        final int userId = mStartedUsers.keyAt(i);
6224                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6225                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6226                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6227                        broadcastIntentLocked(null, null, intent, null,
6228                                new IIntentReceiver.Stub() {
6229                                    @Override
6230                                    public void performReceive(Intent intent, int resultCode,
6231                                            String data, Bundle extras, boolean ordered,
6232                                            boolean sticky, int sendingUser) {
6233                                        synchronized (ActivityManagerService.this) {
6234                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6235                                                    true, false);
6236                                        }
6237                                    }
6238                                },
6239                                0, null, null,
6240                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6241                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6242                                userId);
6243                    }
6244                }
6245                scheduleStartProfilesLocked();
6246            }
6247        }
6248    }
6249
6250    @Override
6251    public void bootAnimationComplete() {
6252        final boolean callFinishBooting;
6253        synchronized (this) {
6254            callFinishBooting = mCallFinishBooting;
6255            mBootAnimationComplete = true;
6256        }
6257        if (callFinishBooting) {
6258            finishBooting();
6259        }
6260    }
6261
6262    @Override
6263    public void systemBackupRestored() {
6264        synchronized (this) {
6265            if (mSystemReady) {
6266                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6267            } else {
6268                Slog.w(TAG, "System backup restored before system is ready");
6269            }
6270        }
6271    }
6272
6273    final void ensureBootCompleted() {
6274        boolean booting;
6275        boolean enableScreen;
6276        synchronized (this) {
6277            booting = mBooting;
6278            mBooting = false;
6279            enableScreen = !mBooted;
6280            mBooted = true;
6281        }
6282
6283        if (booting) {
6284            finishBooting();
6285        }
6286
6287        if (enableScreen) {
6288            enableScreenAfterBoot();
6289        }
6290    }
6291
6292    @Override
6293    public final void activityResumed(IBinder token) {
6294        final long origId = Binder.clearCallingIdentity();
6295        synchronized(this) {
6296            ActivityStack stack = ActivityRecord.getStackLocked(token);
6297            if (stack != null) {
6298                ActivityRecord.activityResumedLocked(token);
6299            }
6300        }
6301        Binder.restoreCallingIdentity(origId);
6302    }
6303
6304    @Override
6305    public final void activityPaused(IBinder token) {
6306        final long origId = Binder.clearCallingIdentity();
6307        synchronized(this) {
6308            ActivityStack stack = ActivityRecord.getStackLocked(token);
6309            if (stack != null) {
6310                stack.activityPausedLocked(token, false);
6311            }
6312        }
6313        Binder.restoreCallingIdentity(origId);
6314    }
6315
6316    @Override
6317    public final void activityStopped(IBinder token, Bundle icicle,
6318            PersistableBundle persistentState, CharSequence description) {
6319        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6320
6321        // Refuse possible leaked file descriptors
6322        if (icicle != null && icicle.hasFileDescriptors()) {
6323            throw new IllegalArgumentException("File descriptors passed in Bundle");
6324        }
6325
6326        final long origId = Binder.clearCallingIdentity();
6327
6328        synchronized (this) {
6329            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6330            if (r != null) {
6331                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6332            }
6333        }
6334
6335        trimApplications();
6336
6337        Binder.restoreCallingIdentity(origId);
6338    }
6339
6340    @Override
6341    public final void activityDestroyed(IBinder token) {
6342        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6343        synchronized (this) {
6344            ActivityStack stack = ActivityRecord.getStackLocked(token);
6345            if (stack != null) {
6346                stack.activityDestroyedLocked(token, "activityDestroyed");
6347            }
6348        }
6349    }
6350
6351    @Override
6352    public final void backgroundResourcesReleased(IBinder token) {
6353        final long origId = Binder.clearCallingIdentity();
6354        try {
6355            synchronized (this) {
6356                ActivityStack stack = ActivityRecord.getStackLocked(token);
6357                if (stack != null) {
6358                    stack.backgroundResourcesReleased();
6359                }
6360            }
6361        } finally {
6362            Binder.restoreCallingIdentity(origId);
6363        }
6364    }
6365
6366    @Override
6367    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6368        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6369    }
6370
6371    @Override
6372    public final void notifyEnterAnimationComplete(IBinder token) {
6373        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6374    }
6375
6376    @Override
6377    public String getCallingPackage(IBinder token) {
6378        synchronized (this) {
6379            ActivityRecord r = getCallingRecordLocked(token);
6380            return r != null ? r.info.packageName : null;
6381        }
6382    }
6383
6384    @Override
6385    public ComponentName getCallingActivity(IBinder token) {
6386        synchronized (this) {
6387            ActivityRecord r = getCallingRecordLocked(token);
6388            return r != null ? r.intent.getComponent() : null;
6389        }
6390    }
6391
6392    private ActivityRecord getCallingRecordLocked(IBinder token) {
6393        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6394        if (r == null) {
6395            return null;
6396        }
6397        return r.resultTo;
6398    }
6399
6400    @Override
6401    public ComponentName getActivityClassForToken(IBinder token) {
6402        synchronized(this) {
6403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6404            if (r == null) {
6405                return null;
6406            }
6407            return r.intent.getComponent();
6408        }
6409    }
6410
6411    @Override
6412    public String getPackageForToken(IBinder token) {
6413        synchronized(this) {
6414            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6415            if (r == null) {
6416                return null;
6417            }
6418            return r.packageName;
6419        }
6420    }
6421
6422    @Override
6423    public IIntentSender getIntentSender(int type,
6424            String packageName, IBinder token, String resultWho,
6425            int requestCode, Intent[] intents, String[] resolvedTypes,
6426            int flags, Bundle options, int userId) {
6427        enforceNotIsolatedCaller("getIntentSender");
6428        // Refuse possible leaked file descriptors
6429        if (intents != null) {
6430            if (intents.length < 1) {
6431                throw new IllegalArgumentException("Intents array length must be >= 1");
6432            }
6433            for (int i=0; i<intents.length; i++) {
6434                Intent intent = intents[i];
6435                if (intent != null) {
6436                    if (intent.hasFileDescriptors()) {
6437                        throw new IllegalArgumentException("File descriptors passed in Intent");
6438                    }
6439                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6440                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6441                        throw new IllegalArgumentException(
6442                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6443                    }
6444                    intents[i] = new Intent(intent);
6445                }
6446            }
6447            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6448                throw new IllegalArgumentException(
6449                        "Intent array length does not match resolvedTypes length");
6450            }
6451        }
6452        if (options != null) {
6453            if (options.hasFileDescriptors()) {
6454                throw new IllegalArgumentException("File descriptors passed in options");
6455            }
6456        }
6457
6458        synchronized(this) {
6459            int callingUid = Binder.getCallingUid();
6460            int origUserId = userId;
6461            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6462                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6463                    ALLOW_NON_FULL, "getIntentSender", null);
6464            if (origUserId == UserHandle.USER_CURRENT) {
6465                // We don't want to evaluate this until the pending intent is
6466                // actually executed.  However, we do want to always do the
6467                // security checking for it above.
6468                userId = UserHandle.USER_CURRENT;
6469            }
6470            try {
6471                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6472                    int uid = AppGlobals.getPackageManager()
6473                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6474                    if (!UserHandle.isSameApp(callingUid, uid)) {
6475                        String msg = "Permission Denial: getIntentSender() from pid="
6476                            + Binder.getCallingPid()
6477                            + ", uid=" + Binder.getCallingUid()
6478                            + ", (need uid=" + uid + ")"
6479                            + " is not allowed to send as package " + packageName;
6480                        Slog.w(TAG, msg);
6481                        throw new SecurityException(msg);
6482                    }
6483                }
6484
6485                return getIntentSenderLocked(type, packageName, callingUid, userId,
6486                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6487
6488            } catch (RemoteException e) {
6489                throw new SecurityException(e);
6490            }
6491        }
6492    }
6493
6494    IIntentSender getIntentSenderLocked(int type, String packageName,
6495            int callingUid, int userId, IBinder token, String resultWho,
6496            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6497            Bundle options) {
6498        if (DEBUG_MU)
6499            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6500        ActivityRecord activity = null;
6501        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6502            activity = ActivityRecord.isInStackLocked(token);
6503            if (activity == null) {
6504                return null;
6505            }
6506            if (activity.finishing) {
6507                return null;
6508            }
6509        }
6510
6511        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6512        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6513        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6514        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6515                |PendingIntent.FLAG_UPDATE_CURRENT);
6516
6517        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6518                type, packageName, activity, resultWho,
6519                requestCode, intents, resolvedTypes, flags, options, userId);
6520        WeakReference<PendingIntentRecord> ref;
6521        ref = mIntentSenderRecords.get(key);
6522        PendingIntentRecord rec = ref != null ? ref.get() : null;
6523        if (rec != null) {
6524            if (!cancelCurrent) {
6525                if (updateCurrent) {
6526                    if (rec.key.requestIntent != null) {
6527                        rec.key.requestIntent.replaceExtras(intents != null ?
6528                                intents[intents.length - 1] : null);
6529                    }
6530                    if (intents != null) {
6531                        intents[intents.length-1] = rec.key.requestIntent;
6532                        rec.key.allIntents = intents;
6533                        rec.key.allResolvedTypes = resolvedTypes;
6534                    } else {
6535                        rec.key.allIntents = null;
6536                        rec.key.allResolvedTypes = null;
6537                    }
6538                }
6539                return rec;
6540            }
6541            rec.canceled = true;
6542            mIntentSenderRecords.remove(key);
6543        }
6544        if (noCreate) {
6545            return rec;
6546        }
6547        rec = new PendingIntentRecord(this, key, callingUid);
6548        mIntentSenderRecords.put(key, rec.ref);
6549        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6550            if (activity.pendingResults == null) {
6551                activity.pendingResults
6552                        = new HashSet<WeakReference<PendingIntentRecord>>();
6553            }
6554            activity.pendingResults.add(rec.ref);
6555        }
6556        return rec;
6557    }
6558
6559    @Override
6560    public void cancelIntentSender(IIntentSender sender) {
6561        if (!(sender instanceof PendingIntentRecord)) {
6562            return;
6563        }
6564        synchronized(this) {
6565            PendingIntentRecord rec = (PendingIntentRecord)sender;
6566            try {
6567                int uid = AppGlobals.getPackageManager()
6568                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6569                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6570                    String msg = "Permission Denial: cancelIntentSender() from pid="
6571                        + Binder.getCallingPid()
6572                        + ", uid=" + Binder.getCallingUid()
6573                        + " is not allowed to cancel packges "
6574                        + rec.key.packageName;
6575                    Slog.w(TAG, msg);
6576                    throw new SecurityException(msg);
6577                }
6578            } catch (RemoteException e) {
6579                throw new SecurityException(e);
6580            }
6581            cancelIntentSenderLocked(rec, true);
6582        }
6583    }
6584
6585    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6586        rec.canceled = true;
6587        mIntentSenderRecords.remove(rec.key);
6588        if (cleanActivity && rec.key.activity != null) {
6589            rec.key.activity.pendingResults.remove(rec.ref);
6590        }
6591    }
6592
6593    @Override
6594    public String getPackageForIntentSender(IIntentSender pendingResult) {
6595        if (!(pendingResult instanceof PendingIntentRecord)) {
6596            return null;
6597        }
6598        try {
6599            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6600            return res.key.packageName;
6601        } catch (ClassCastException e) {
6602        }
6603        return null;
6604    }
6605
6606    @Override
6607    public int getUidForIntentSender(IIntentSender sender) {
6608        if (sender instanceof PendingIntentRecord) {
6609            try {
6610                PendingIntentRecord res = (PendingIntentRecord)sender;
6611                return res.uid;
6612            } catch (ClassCastException e) {
6613            }
6614        }
6615        return -1;
6616    }
6617
6618    @Override
6619    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6620        if (!(pendingResult instanceof PendingIntentRecord)) {
6621            return false;
6622        }
6623        try {
6624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6625            if (res.key.allIntents == null) {
6626                return false;
6627            }
6628            for (int i=0; i<res.key.allIntents.length; i++) {
6629                Intent intent = res.key.allIntents[i];
6630                if (intent.getPackage() != null && intent.getComponent() != null) {
6631                    return false;
6632                }
6633            }
6634            return true;
6635        } catch (ClassCastException e) {
6636        }
6637        return false;
6638    }
6639
6640    @Override
6641    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6642        if (!(pendingResult instanceof PendingIntentRecord)) {
6643            return false;
6644        }
6645        try {
6646            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6647            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6648                return true;
6649            }
6650            return false;
6651        } catch (ClassCastException e) {
6652        }
6653        return false;
6654    }
6655
6656    @Override
6657    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6658        if (!(pendingResult instanceof PendingIntentRecord)) {
6659            return null;
6660        }
6661        try {
6662            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6663            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6664        } catch (ClassCastException e) {
6665        }
6666        return null;
6667    }
6668
6669    @Override
6670    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6671        if (!(pendingResult instanceof PendingIntentRecord)) {
6672            return null;
6673        }
6674        try {
6675            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6676            Intent intent = res.key.requestIntent;
6677            if (intent != null) {
6678                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6679                        || res.lastTagPrefix.equals(prefix))) {
6680                    return res.lastTag;
6681                }
6682                res.lastTagPrefix = prefix;
6683                StringBuilder sb = new StringBuilder(128);
6684                if (prefix != null) {
6685                    sb.append(prefix);
6686                }
6687                if (intent.getAction() != null) {
6688                    sb.append(intent.getAction());
6689                } else if (intent.getComponent() != null) {
6690                    intent.getComponent().appendShortString(sb);
6691                } else {
6692                    sb.append("?");
6693                }
6694                return res.lastTag = sb.toString();
6695            }
6696        } catch (ClassCastException e) {
6697        }
6698        return null;
6699    }
6700
6701    @Override
6702    public void setProcessLimit(int max) {
6703        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6704                "setProcessLimit()");
6705        synchronized (this) {
6706            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6707            mProcessLimitOverride = max;
6708        }
6709        trimApplications();
6710    }
6711
6712    @Override
6713    public int getProcessLimit() {
6714        synchronized (this) {
6715            return mProcessLimitOverride;
6716        }
6717    }
6718
6719    void foregroundTokenDied(ForegroundToken token) {
6720        synchronized (ActivityManagerService.this) {
6721            synchronized (mPidsSelfLocked) {
6722                ForegroundToken cur
6723                    = mForegroundProcesses.get(token.pid);
6724                if (cur != token) {
6725                    return;
6726                }
6727                mForegroundProcesses.remove(token.pid);
6728                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6729                if (pr == null) {
6730                    return;
6731                }
6732                pr.forcingToForeground = null;
6733                updateProcessForegroundLocked(pr, false, false);
6734            }
6735            updateOomAdjLocked();
6736        }
6737    }
6738
6739    @Override
6740    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6741        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6742                "setProcessForeground()");
6743        synchronized(this) {
6744            boolean changed = false;
6745
6746            synchronized (mPidsSelfLocked) {
6747                ProcessRecord pr = mPidsSelfLocked.get(pid);
6748                if (pr == null && isForeground) {
6749                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6750                    return;
6751                }
6752                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6753                if (oldToken != null) {
6754                    oldToken.token.unlinkToDeath(oldToken, 0);
6755                    mForegroundProcesses.remove(pid);
6756                    if (pr != null) {
6757                        pr.forcingToForeground = null;
6758                    }
6759                    changed = true;
6760                }
6761                if (isForeground && token != null) {
6762                    ForegroundToken newToken = new ForegroundToken() {
6763                        @Override
6764                        public void binderDied() {
6765                            foregroundTokenDied(this);
6766                        }
6767                    };
6768                    newToken.pid = pid;
6769                    newToken.token = token;
6770                    try {
6771                        token.linkToDeath(newToken, 0);
6772                        mForegroundProcesses.put(pid, newToken);
6773                        pr.forcingToForeground = token;
6774                        changed = true;
6775                    } catch (RemoteException e) {
6776                        // If the process died while doing this, we will later
6777                        // do the cleanup with the process death link.
6778                    }
6779                }
6780            }
6781
6782            if (changed) {
6783                updateOomAdjLocked();
6784            }
6785        }
6786    }
6787
6788    // =========================================================
6789    // PERMISSIONS
6790    // =========================================================
6791
6792    static class PermissionController extends IPermissionController.Stub {
6793        ActivityManagerService mActivityManagerService;
6794        PermissionController(ActivityManagerService activityManagerService) {
6795            mActivityManagerService = activityManagerService;
6796        }
6797
6798        @Override
6799        public boolean checkPermission(String permission, int pid, int uid) {
6800            return mActivityManagerService.checkPermission(permission, pid,
6801                    uid) == PackageManager.PERMISSION_GRANTED;
6802        }
6803    }
6804
6805    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6806        @Override
6807        public int checkComponentPermission(String permission, int pid, int uid,
6808                int owningUid, boolean exported) {
6809            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6810                    owningUid, exported);
6811        }
6812
6813        @Override
6814        public Object getAMSLock() {
6815            return ActivityManagerService.this;
6816        }
6817    }
6818
6819    /**
6820     * This can be called with or without the global lock held.
6821     */
6822    int checkComponentPermission(String permission, int pid, int uid,
6823            int owningUid, boolean exported) {
6824        if (pid == MY_PID) {
6825            return PackageManager.PERMISSION_GRANTED;
6826        }
6827        return ActivityManager.checkComponentPermission(permission, uid,
6828                owningUid, exported);
6829    }
6830
6831    /**
6832     * As the only public entry point for permissions checking, this method
6833     * can enforce the semantic that requesting a check on a null global
6834     * permission is automatically denied.  (Internally a null permission
6835     * string is used when calling {@link #checkComponentPermission} in cases
6836     * when only uid-based security is needed.)
6837     *
6838     * This can be called with or without the global lock held.
6839     */
6840    @Override
6841    public int checkPermission(String permission, int pid, int uid) {
6842        if (permission == null) {
6843            return PackageManager.PERMISSION_DENIED;
6844        }
6845        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6846    }
6847
6848    @Override
6849    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6850        if (permission == null) {
6851            return PackageManager.PERMISSION_DENIED;
6852        }
6853
6854        // We might be performing an operation on behalf of an indirect binder
6855        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6856        // client identity accordingly before proceeding.
6857        Identity tlsIdentity = sCallerIdentity.get();
6858        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6859            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6860                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6861            uid = tlsIdentity.uid;
6862            pid = tlsIdentity.pid;
6863        }
6864
6865        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6866    }
6867
6868    /**
6869     * Binder IPC calls go through the public entry point.
6870     * This can be called with or without the global lock held.
6871     */
6872    int checkCallingPermission(String permission) {
6873        return checkPermission(permission,
6874                Binder.getCallingPid(),
6875                UserHandle.getAppId(Binder.getCallingUid()));
6876    }
6877
6878    /**
6879     * This can be called with or without the global lock held.
6880     */
6881    void enforceCallingPermission(String permission, String func) {
6882        if (checkCallingPermission(permission)
6883                == PackageManager.PERMISSION_GRANTED) {
6884            return;
6885        }
6886
6887        String msg = "Permission Denial: " + func + " from pid="
6888                + Binder.getCallingPid()
6889                + ", uid=" + Binder.getCallingUid()
6890                + " requires " + permission;
6891        Slog.w(TAG, msg);
6892        throw new SecurityException(msg);
6893    }
6894
6895    /**
6896     * Determine if UID is holding permissions required to access {@link Uri} in
6897     * the given {@link ProviderInfo}. Final permission checking is always done
6898     * in {@link ContentProvider}.
6899     */
6900    private final boolean checkHoldingPermissionsLocked(
6901            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6902        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6903                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6904        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6905            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6906                    != PERMISSION_GRANTED) {
6907                return false;
6908            }
6909        }
6910        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6911    }
6912
6913    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6914            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6915        if (pi.applicationInfo.uid == uid) {
6916            return true;
6917        } else if (!pi.exported) {
6918            return false;
6919        }
6920
6921        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6922        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6923        try {
6924            // check if target holds top-level <provider> permissions
6925            if (!readMet && pi.readPermission != null && considerUidPermissions
6926                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6927                readMet = true;
6928            }
6929            if (!writeMet && pi.writePermission != null && considerUidPermissions
6930                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6931                writeMet = true;
6932            }
6933
6934            // track if unprotected read/write is allowed; any denied
6935            // <path-permission> below removes this ability
6936            boolean allowDefaultRead = pi.readPermission == null;
6937            boolean allowDefaultWrite = pi.writePermission == null;
6938
6939            // check if target holds any <path-permission> that match uri
6940            final PathPermission[] pps = pi.pathPermissions;
6941            if (pps != null) {
6942                final String path = grantUri.uri.getPath();
6943                int i = pps.length;
6944                while (i > 0 && (!readMet || !writeMet)) {
6945                    i--;
6946                    PathPermission pp = pps[i];
6947                    if (pp.match(path)) {
6948                        if (!readMet) {
6949                            final String pprperm = pp.getReadPermission();
6950                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6951                                    + pprperm + " for " + pp.getPath()
6952                                    + ": match=" + pp.match(path)
6953                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6954                            if (pprperm != null) {
6955                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6956                                        == PERMISSION_GRANTED) {
6957                                    readMet = true;
6958                                } else {
6959                                    allowDefaultRead = false;
6960                                }
6961                            }
6962                        }
6963                        if (!writeMet) {
6964                            final String ppwperm = pp.getWritePermission();
6965                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6966                                    + ppwperm + " for " + pp.getPath()
6967                                    + ": match=" + pp.match(path)
6968                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6969                            if (ppwperm != null) {
6970                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6971                                        == PERMISSION_GRANTED) {
6972                                    writeMet = true;
6973                                } else {
6974                                    allowDefaultWrite = false;
6975                                }
6976                            }
6977                        }
6978                    }
6979                }
6980            }
6981
6982            // grant unprotected <provider> read/write, if not blocked by
6983            // <path-permission> above
6984            if (allowDefaultRead) readMet = true;
6985            if (allowDefaultWrite) writeMet = true;
6986
6987        } catch (RemoteException e) {
6988            return false;
6989        }
6990
6991        return readMet && writeMet;
6992    }
6993
6994    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6995        ProviderInfo pi = null;
6996        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6997        if (cpr != null) {
6998            pi = cpr.info;
6999        } else {
7000            try {
7001                pi = AppGlobals.getPackageManager().resolveContentProvider(
7002                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7003            } catch (RemoteException ex) {
7004            }
7005        }
7006        return pi;
7007    }
7008
7009    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7010        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7011        if (targetUris != null) {
7012            return targetUris.get(grantUri);
7013        }
7014        return null;
7015    }
7016
7017    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7018            String targetPkg, int targetUid, GrantUri grantUri) {
7019        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7020        if (targetUris == null) {
7021            targetUris = Maps.newArrayMap();
7022            mGrantedUriPermissions.put(targetUid, targetUris);
7023        }
7024
7025        UriPermission perm = targetUris.get(grantUri);
7026        if (perm == null) {
7027            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7028            targetUris.put(grantUri, perm);
7029        }
7030
7031        return perm;
7032    }
7033
7034    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7035            final int modeFlags) {
7036        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7037        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7038                : UriPermission.STRENGTH_OWNED;
7039
7040        // Root gets to do everything.
7041        if (uid == 0) {
7042            return true;
7043        }
7044
7045        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7046        if (perms == null) return false;
7047
7048        // First look for exact match
7049        final UriPermission exactPerm = perms.get(grantUri);
7050        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7051            return true;
7052        }
7053
7054        // No exact match, look for prefixes
7055        final int N = perms.size();
7056        for (int i = 0; i < N; i++) {
7057            final UriPermission perm = perms.valueAt(i);
7058            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7059                    && perm.getStrength(modeFlags) >= minStrength) {
7060                return true;
7061            }
7062        }
7063
7064        return false;
7065    }
7066
7067    /**
7068     * @param uri This uri must NOT contain an embedded userId.
7069     * @param userId The userId in which the uri is to be resolved.
7070     */
7071    @Override
7072    public int checkUriPermission(Uri uri, int pid, int uid,
7073            final int modeFlags, int userId, IBinder callerToken) {
7074        enforceNotIsolatedCaller("checkUriPermission");
7075
7076        // Another redirected-binder-call permissions check as in
7077        // {@link checkPermissionWithToken}.
7078        Identity tlsIdentity = sCallerIdentity.get();
7079        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7080            uid = tlsIdentity.uid;
7081            pid = tlsIdentity.pid;
7082        }
7083
7084        // Our own process gets to do everything.
7085        if (pid == MY_PID) {
7086            return PackageManager.PERMISSION_GRANTED;
7087        }
7088        synchronized (this) {
7089            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7090                    ? PackageManager.PERMISSION_GRANTED
7091                    : PackageManager.PERMISSION_DENIED;
7092        }
7093    }
7094
7095    /**
7096     * Check if the targetPkg can be granted permission to access uri by
7097     * the callingUid using the given modeFlags.  Throws a security exception
7098     * if callingUid is not allowed to do this.  Returns the uid of the target
7099     * if the URI permission grant should be performed; returns -1 if it is not
7100     * needed (for example targetPkg already has permission to access the URI).
7101     * If you already know the uid of the target, you can supply it in
7102     * lastTargetUid else set that to -1.
7103     */
7104    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7105            final int modeFlags, int lastTargetUid) {
7106        if (!Intent.isAccessUriMode(modeFlags)) {
7107            return -1;
7108        }
7109
7110        if (targetPkg != null) {
7111            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7112                    "Checking grant " + targetPkg + " permission to " + grantUri);
7113        }
7114
7115        final IPackageManager pm = AppGlobals.getPackageManager();
7116
7117        // If this is not a content: uri, we can't do anything with it.
7118        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7119            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7120                    "Can't grant URI permission for non-content URI: " + grantUri);
7121            return -1;
7122        }
7123
7124        final String authority = grantUri.uri.getAuthority();
7125        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7126        if (pi == null) {
7127            Slog.w(TAG, "No content provider found for permission check: " +
7128                    grantUri.uri.toSafeString());
7129            return -1;
7130        }
7131
7132        int targetUid = lastTargetUid;
7133        if (targetUid < 0 && targetPkg != null) {
7134            try {
7135                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7136                if (targetUid < 0) {
7137                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7138                            "Can't grant URI permission no uid for: " + targetPkg);
7139                    return -1;
7140                }
7141            } catch (RemoteException ex) {
7142                return -1;
7143            }
7144        }
7145
7146        if (targetUid >= 0) {
7147            // First...  does the target actually need this permission?
7148            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7149                // No need to grant the target this permission.
7150                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7151                        "Target " + targetPkg + " already has full permission to " + grantUri);
7152                return -1;
7153            }
7154        } else {
7155            // First...  there is no target package, so can anyone access it?
7156            boolean allowed = pi.exported;
7157            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7158                if (pi.readPermission != null) {
7159                    allowed = false;
7160                }
7161            }
7162            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7163                if (pi.writePermission != null) {
7164                    allowed = false;
7165                }
7166            }
7167            if (allowed) {
7168                return -1;
7169            }
7170        }
7171
7172        /* There is a special cross user grant if:
7173         * - The target is on another user.
7174         * - Apps on the current user can access the uri without any uid permissions.
7175         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7176         * grant uri permissions.
7177         */
7178        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7179                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7180                modeFlags, false /*without considering the uid permissions*/);
7181
7182        // Second...  is the provider allowing granting of URI permissions?
7183        if (!specialCrossUserGrant) {
7184            if (!pi.grantUriPermissions) {
7185                throw new SecurityException("Provider " + pi.packageName
7186                        + "/" + pi.name
7187                        + " does not allow granting of Uri permissions (uri "
7188                        + grantUri + ")");
7189            }
7190            if (pi.uriPermissionPatterns != null) {
7191                final int N = pi.uriPermissionPatterns.length;
7192                boolean allowed = false;
7193                for (int i=0; i<N; i++) {
7194                    if (pi.uriPermissionPatterns[i] != null
7195                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7196                        allowed = true;
7197                        break;
7198                    }
7199                }
7200                if (!allowed) {
7201                    throw new SecurityException("Provider " + pi.packageName
7202                            + "/" + pi.name
7203                            + " does not allow granting of permission to path of Uri "
7204                            + grantUri);
7205                }
7206            }
7207        }
7208
7209        // Third...  does the caller itself have permission to access
7210        // this uri?
7211        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7212            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7213                // Require they hold a strong enough Uri permission
7214                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7215                    throw new SecurityException("Uid " + callingUid
7216                            + " does not have permission to uri " + grantUri);
7217                }
7218            }
7219        }
7220        return targetUid;
7221    }
7222
7223    /**
7224     * @param uri This uri must NOT contain an embedded userId.
7225     * @param userId The userId in which the uri is to be resolved.
7226     */
7227    @Override
7228    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7229            final int modeFlags, int userId) {
7230        enforceNotIsolatedCaller("checkGrantUriPermission");
7231        synchronized(this) {
7232            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7233                    new GrantUri(userId, uri, false), modeFlags, -1);
7234        }
7235    }
7236
7237    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7238            final int modeFlags, UriPermissionOwner owner) {
7239        if (!Intent.isAccessUriMode(modeFlags)) {
7240            return;
7241        }
7242
7243        // So here we are: the caller has the assumed permission
7244        // to the uri, and the target doesn't.  Let's now give this to
7245        // the target.
7246
7247        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7248                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7249
7250        final String authority = grantUri.uri.getAuthority();
7251        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7252        if (pi == null) {
7253            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7254            return;
7255        }
7256
7257        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7258            grantUri.prefix = true;
7259        }
7260        final UriPermission perm = findOrCreateUriPermissionLocked(
7261                pi.packageName, targetPkg, targetUid, grantUri);
7262        perm.grantModes(modeFlags, owner);
7263    }
7264
7265    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7266            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7267        if (targetPkg == null) {
7268            throw new NullPointerException("targetPkg");
7269        }
7270        int targetUid;
7271        final IPackageManager pm = AppGlobals.getPackageManager();
7272        try {
7273            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7274        } catch (RemoteException ex) {
7275            return;
7276        }
7277
7278        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7279                targetUid);
7280        if (targetUid < 0) {
7281            return;
7282        }
7283
7284        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7285                owner);
7286    }
7287
7288    static class NeededUriGrants extends ArrayList<GrantUri> {
7289        final String targetPkg;
7290        final int targetUid;
7291        final int flags;
7292
7293        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7294            this.targetPkg = targetPkg;
7295            this.targetUid = targetUid;
7296            this.flags = flags;
7297        }
7298    }
7299
7300    /**
7301     * Like checkGrantUriPermissionLocked, but takes an Intent.
7302     */
7303    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7304            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7305        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7306                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7307                + " clip=" + (intent != null ? intent.getClipData() : null)
7308                + " from " + intent + "; flags=0x"
7309                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7310
7311        if (targetPkg == null) {
7312            throw new NullPointerException("targetPkg");
7313        }
7314
7315        if (intent == null) {
7316            return null;
7317        }
7318        Uri data = intent.getData();
7319        ClipData clip = intent.getClipData();
7320        if (data == null && clip == null) {
7321            return null;
7322        }
7323        // Default userId for uris in the intent (if they don't specify it themselves)
7324        int contentUserHint = intent.getContentUserHint();
7325        if (contentUserHint == UserHandle.USER_CURRENT) {
7326            contentUserHint = UserHandle.getUserId(callingUid);
7327        }
7328        final IPackageManager pm = AppGlobals.getPackageManager();
7329        int targetUid;
7330        if (needed != null) {
7331            targetUid = needed.targetUid;
7332        } else {
7333            try {
7334                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7335            } catch (RemoteException ex) {
7336                return null;
7337            }
7338            if (targetUid < 0) {
7339                if (DEBUG_URI_PERMISSION) {
7340                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7341                            + " on user " + targetUserId);
7342                }
7343                return null;
7344            }
7345        }
7346        if (data != null) {
7347            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7348            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7349                    targetUid);
7350            if (targetUid > 0) {
7351                if (needed == null) {
7352                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7353                }
7354                needed.add(grantUri);
7355            }
7356        }
7357        if (clip != null) {
7358            for (int i=0; i<clip.getItemCount(); i++) {
7359                Uri uri = clip.getItemAt(i).getUri();
7360                if (uri != null) {
7361                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7362                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7363                            targetUid);
7364                    if (targetUid > 0) {
7365                        if (needed == null) {
7366                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7367                        }
7368                        needed.add(grantUri);
7369                    }
7370                } else {
7371                    Intent clipIntent = clip.getItemAt(i).getIntent();
7372                    if (clipIntent != null) {
7373                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7374                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7375                        if (newNeeded != null) {
7376                            needed = newNeeded;
7377                        }
7378                    }
7379                }
7380            }
7381        }
7382
7383        return needed;
7384    }
7385
7386    /**
7387     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7388     */
7389    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7390            UriPermissionOwner owner) {
7391        if (needed != null) {
7392            for (int i=0; i<needed.size(); i++) {
7393                GrantUri grantUri = needed.get(i);
7394                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7395                        grantUri, needed.flags, owner);
7396            }
7397        }
7398    }
7399
7400    void grantUriPermissionFromIntentLocked(int callingUid,
7401            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7402        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7403                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7404        if (needed == null) {
7405            return;
7406        }
7407
7408        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7409    }
7410
7411    /**
7412     * @param uri This uri must NOT contain an embedded userId.
7413     * @param userId The userId in which the uri is to be resolved.
7414     */
7415    @Override
7416    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7417            final int modeFlags, int userId) {
7418        enforceNotIsolatedCaller("grantUriPermission");
7419        GrantUri grantUri = new GrantUri(userId, uri, false);
7420        synchronized(this) {
7421            final ProcessRecord r = getRecordForAppLocked(caller);
7422            if (r == null) {
7423                throw new SecurityException("Unable to find app for caller "
7424                        + caller
7425                        + " when granting permission to uri " + grantUri);
7426            }
7427            if (targetPkg == null) {
7428                throw new IllegalArgumentException("null target");
7429            }
7430            if (grantUri == null) {
7431                throw new IllegalArgumentException("null uri");
7432            }
7433
7434            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7435                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7436                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7437                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7438
7439            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7440                    UserHandle.getUserId(r.uid));
7441        }
7442    }
7443
7444    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7445        if (perm.modeFlags == 0) {
7446            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7447                    perm.targetUid);
7448            if (perms != null) {
7449                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7450                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7451
7452                perms.remove(perm.uri);
7453                if (perms.isEmpty()) {
7454                    mGrantedUriPermissions.remove(perm.targetUid);
7455                }
7456            }
7457        }
7458    }
7459
7460    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7461        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7462
7463        final IPackageManager pm = AppGlobals.getPackageManager();
7464        final String authority = grantUri.uri.getAuthority();
7465        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7466        if (pi == null) {
7467            Slog.w(TAG, "No content provider found for permission revoke: "
7468                    + grantUri.toSafeString());
7469            return;
7470        }
7471
7472        // Does the caller have this permission on the URI?
7473        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7474            // If they don't have direct access to the URI, then revoke any
7475            // ownerless URI permissions that have been granted to them.
7476            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7477            if (perms != null) {
7478                boolean persistChanged = false;
7479                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7480                    final UriPermission perm = it.next();
7481                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7482                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7483                        if (DEBUG_URI_PERMISSION)
7484                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7485                                    " permission to " + perm.uri);
7486                        persistChanged |= perm.revokeModes(
7487                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7488                        if (perm.modeFlags == 0) {
7489                            it.remove();
7490                        }
7491                    }
7492                }
7493                if (perms.isEmpty()) {
7494                    mGrantedUriPermissions.remove(callingUid);
7495                }
7496                if (persistChanged) {
7497                    schedulePersistUriGrants();
7498                }
7499            }
7500            return;
7501        }
7502
7503        boolean persistChanged = false;
7504
7505        // Go through all of the permissions and remove any that match.
7506        int N = mGrantedUriPermissions.size();
7507        for (int i = 0; i < N; i++) {
7508            final int targetUid = mGrantedUriPermissions.keyAt(i);
7509            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7510
7511            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7512                final UriPermission perm = it.next();
7513                if (perm.uri.sourceUserId == grantUri.sourceUserId
7514                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7515                    if (DEBUG_URI_PERMISSION)
7516                        Slog.v(TAG,
7517                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7518                    persistChanged |= perm.revokeModes(
7519                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7520                    if (perm.modeFlags == 0) {
7521                        it.remove();
7522                    }
7523                }
7524            }
7525
7526            if (perms.isEmpty()) {
7527                mGrantedUriPermissions.remove(targetUid);
7528                N--;
7529                i--;
7530            }
7531        }
7532
7533        if (persistChanged) {
7534            schedulePersistUriGrants();
7535        }
7536    }
7537
7538    /**
7539     * @param uri This uri must NOT contain an embedded userId.
7540     * @param userId The userId in which the uri is to be resolved.
7541     */
7542    @Override
7543    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7544            int userId) {
7545        enforceNotIsolatedCaller("revokeUriPermission");
7546        synchronized(this) {
7547            final ProcessRecord r = getRecordForAppLocked(caller);
7548            if (r == null) {
7549                throw new SecurityException("Unable to find app for caller "
7550                        + caller
7551                        + " when revoking permission to uri " + uri);
7552            }
7553            if (uri == null) {
7554                Slog.w(TAG, "revokeUriPermission: null uri");
7555                return;
7556            }
7557
7558            if (!Intent.isAccessUriMode(modeFlags)) {
7559                return;
7560            }
7561
7562            final IPackageManager pm = AppGlobals.getPackageManager();
7563            final String authority = uri.getAuthority();
7564            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7565            if (pi == null) {
7566                Slog.w(TAG, "No content provider found for permission revoke: "
7567                        + uri.toSafeString());
7568                return;
7569            }
7570
7571            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7572        }
7573    }
7574
7575    /**
7576     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7577     * given package.
7578     *
7579     * @param packageName Package name to match, or {@code null} to apply to all
7580     *            packages.
7581     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7582     *            to all users.
7583     * @param persistable If persistable grants should be removed.
7584     */
7585    private void removeUriPermissionsForPackageLocked(
7586            String packageName, int userHandle, boolean persistable) {
7587        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7588            throw new IllegalArgumentException("Must narrow by either package or user");
7589        }
7590
7591        boolean persistChanged = false;
7592
7593        int N = mGrantedUriPermissions.size();
7594        for (int i = 0; i < N; i++) {
7595            final int targetUid = mGrantedUriPermissions.keyAt(i);
7596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7597
7598            // Only inspect grants matching user
7599            if (userHandle == UserHandle.USER_ALL
7600                    || userHandle == UserHandle.getUserId(targetUid)) {
7601                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7602                    final UriPermission perm = it.next();
7603
7604                    // Only inspect grants matching package
7605                    if (packageName == null || perm.sourcePkg.equals(packageName)
7606                            || perm.targetPkg.equals(packageName)) {
7607                        persistChanged |= perm.revokeModes(persistable
7608                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7609
7610                        // Only remove when no modes remain; any persisted grants
7611                        // will keep this alive.
7612                        if (perm.modeFlags == 0) {
7613                            it.remove();
7614                        }
7615                    }
7616                }
7617
7618                if (perms.isEmpty()) {
7619                    mGrantedUriPermissions.remove(targetUid);
7620                    N--;
7621                    i--;
7622                }
7623            }
7624        }
7625
7626        if (persistChanged) {
7627            schedulePersistUriGrants();
7628        }
7629    }
7630
7631    @Override
7632    public IBinder newUriPermissionOwner(String name) {
7633        enforceNotIsolatedCaller("newUriPermissionOwner");
7634        synchronized(this) {
7635            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7636            return owner.getExternalTokenLocked();
7637        }
7638    }
7639
7640    /**
7641     * @param uri This uri must NOT contain an embedded userId.
7642     * @param sourceUserId The userId in which the uri is to be resolved.
7643     * @param targetUserId The userId of the app that receives the grant.
7644     */
7645    @Override
7646    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7647            final int modeFlags, int sourceUserId, int targetUserId) {
7648        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7649                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7650        synchronized(this) {
7651            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7652            if (owner == null) {
7653                throw new IllegalArgumentException("Unknown owner: " + token);
7654            }
7655            if (fromUid != Binder.getCallingUid()) {
7656                if (Binder.getCallingUid() != Process.myUid()) {
7657                    // Only system code can grant URI permissions on behalf
7658                    // of other users.
7659                    throw new SecurityException("nice try");
7660                }
7661            }
7662            if (targetPkg == null) {
7663                throw new IllegalArgumentException("null target");
7664            }
7665            if (uri == null) {
7666                throw new IllegalArgumentException("null uri");
7667            }
7668
7669            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7670                    modeFlags, owner, targetUserId);
7671        }
7672    }
7673
7674    /**
7675     * @param uri This uri must NOT contain an embedded userId.
7676     * @param userId The userId in which the uri is to be resolved.
7677     */
7678    @Override
7679    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7680        synchronized(this) {
7681            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7682            if (owner == null) {
7683                throw new IllegalArgumentException("Unknown owner: " + token);
7684            }
7685
7686            if (uri == null) {
7687                owner.removeUriPermissionsLocked(mode);
7688            } else {
7689                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7690            }
7691        }
7692    }
7693
7694    private void schedulePersistUriGrants() {
7695        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7696            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7697                    10 * DateUtils.SECOND_IN_MILLIS);
7698        }
7699    }
7700
7701    private void writeGrantedUriPermissions() {
7702        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7703
7704        // Snapshot permissions so we can persist without lock
7705        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7706        synchronized (this) {
7707            final int size = mGrantedUriPermissions.size();
7708            for (int i = 0; i < size; i++) {
7709                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7710                for (UriPermission perm : perms.values()) {
7711                    if (perm.persistedModeFlags != 0) {
7712                        persist.add(perm.snapshot());
7713                    }
7714                }
7715            }
7716        }
7717
7718        FileOutputStream fos = null;
7719        try {
7720            fos = mGrantFile.startWrite();
7721
7722            XmlSerializer out = new FastXmlSerializer();
7723            out.setOutput(fos, "utf-8");
7724            out.startDocument(null, true);
7725            out.startTag(null, TAG_URI_GRANTS);
7726            for (UriPermission.Snapshot perm : persist) {
7727                out.startTag(null, TAG_URI_GRANT);
7728                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7729                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7730                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7731                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7732                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7733                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7734                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7735                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7736                out.endTag(null, TAG_URI_GRANT);
7737            }
7738            out.endTag(null, TAG_URI_GRANTS);
7739            out.endDocument();
7740
7741            mGrantFile.finishWrite(fos);
7742        } catch (IOException e) {
7743            if (fos != null) {
7744                mGrantFile.failWrite(fos);
7745            }
7746        }
7747    }
7748
7749    private void readGrantedUriPermissionsLocked() {
7750        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7751
7752        final long now = System.currentTimeMillis();
7753
7754        FileInputStream fis = null;
7755        try {
7756            fis = mGrantFile.openRead();
7757            final XmlPullParser in = Xml.newPullParser();
7758            in.setInput(fis, null);
7759
7760            int type;
7761            while ((type = in.next()) != END_DOCUMENT) {
7762                final String tag = in.getName();
7763                if (type == START_TAG) {
7764                    if (TAG_URI_GRANT.equals(tag)) {
7765                        final int sourceUserId;
7766                        final int targetUserId;
7767                        final int userHandle = readIntAttribute(in,
7768                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7769                        if (userHandle != UserHandle.USER_NULL) {
7770                            // For backwards compatibility.
7771                            sourceUserId = userHandle;
7772                            targetUserId = userHandle;
7773                        } else {
7774                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7775                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7776                        }
7777                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7778                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7779                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7780                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7781                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7782                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7783
7784                        // Sanity check that provider still belongs to source package
7785                        final ProviderInfo pi = getProviderInfoLocked(
7786                                uri.getAuthority(), sourceUserId);
7787                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7788                            int targetUid = -1;
7789                            try {
7790                                targetUid = AppGlobals.getPackageManager()
7791                                        .getPackageUid(targetPkg, targetUserId);
7792                            } catch (RemoteException e) {
7793                            }
7794                            if (targetUid != -1) {
7795                                final UriPermission perm = findOrCreateUriPermissionLocked(
7796                                        sourcePkg, targetPkg, targetUid,
7797                                        new GrantUri(sourceUserId, uri, prefix));
7798                                perm.initPersistedModes(modeFlags, createdTime);
7799                            }
7800                        } else {
7801                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7802                                    + " but instead found " + pi);
7803                        }
7804                    }
7805                }
7806            }
7807        } catch (FileNotFoundException e) {
7808            // Missing grants is okay
7809        } catch (IOException e) {
7810            Slog.wtf(TAG, "Failed reading Uri grants", e);
7811        } catch (XmlPullParserException e) {
7812            Slog.wtf(TAG, "Failed reading Uri grants", e);
7813        } finally {
7814            IoUtils.closeQuietly(fis);
7815        }
7816    }
7817
7818    /**
7819     * @param uri This uri must NOT contain an embedded userId.
7820     * @param userId The userId in which the uri is to be resolved.
7821     */
7822    @Override
7823    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7824        enforceNotIsolatedCaller("takePersistableUriPermission");
7825
7826        Preconditions.checkFlagsArgument(modeFlags,
7827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7828
7829        synchronized (this) {
7830            final int callingUid = Binder.getCallingUid();
7831            boolean persistChanged = false;
7832            GrantUri grantUri = new GrantUri(userId, uri, false);
7833
7834            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7835                    new GrantUri(userId, uri, false));
7836            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7837                    new GrantUri(userId, uri, true));
7838
7839            final boolean exactValid = (exactPerm != null)
7840                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7841            final boolean prefixValid = (prefixPerm != null)
7842                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7843
7844            if (!(exactValid || prefixValid)) {
7845                throw new SecurityException("No persistable permission grants found for UID "
7846                        + callingUid + " and Uri " + grantUri.toSafeString());
7847            }
7848
7849            if (exactValid) {
7850                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7851            }
7852            if (prefixValid) {
7853                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7854            }
7855
7856            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7857
7858            if (persistChanged) {
7859                schedulePersistUriGrants();
7860            }
7861        }
7862    }
7863
7864    /**
7865     * @param uri This uri must NOT contain an embedded userId.
7866     * @param userId The userId in which the uri is to be resolved.
7867     */
7868    @Override
7869    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7870        enforceNotIsolatedCaller("releasePersistableUriPermission");
7871
7872        Preconditions.checkFlagsArgument(modeFlags,
7873                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7874
7875        synchronized (this) {
7876            final int callingUid = Binder.getCallingUid();
7877            boolean persistChanged = false;
7878
7879            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7880                    new GrantUri(userId, uri, false));
7881            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7882                    new GrantUri(userId, uri, true));
7883            if (exactPerm == null && prefixPerm == null) {
7884                throw new SecurityException("No permission grants found for UID " + callingUid
7885                        + " and Uri " + uri.toSafeString());
7886            }
7887
7888            if (exactPerm != null) {
7889                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7890                removeUriPermissionIfNeededLocked(exactPerm);
7891            }
7892            if (prefixPerm != null) {
7893                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7894                removeUriPermissionIfNeededLocked(prefixPerm);
7895            }
7896
7897            if (persistChanged) {
7898                schedulePersistUriGrants();
7899            }
7900        }
7901    }
7902
7903    /**
7904     * Prune any older {@link UriPermission} for the given UID until outstanding
7905     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7906     *
7907     * @return if any mutations occured that require persisting.
7908     */
7909    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7910        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7911        if (perms == null) return false;
7912        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7913
7914        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7915        for (UriPermission perm : perms.values()) {
7916            if (perm.persistedModeFlags != 0) {
7917                persisted.add(perm);
7918            }
7919        }
7920
7921        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7922        if (trimCount <= 0) return false;
7923
7924        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7925        for (int i = 0; i < trimCount; i++) {
7926            final UriPermission perm = persisted.get(i);
7927
7928            if (DEBUG_URI_PERMISSION) {
7929                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7930            }
7931
7932            perm.releasePersistableModes(~0);
7933            removeUriPermissionIfNeededLocked(perm);
7934        }
7935
7936        return true;
7937    }
7938
7939    @Override
7940    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7941            String packageName, boolean incoming) {
7942        enforceNotIsolatedCaller("getPersistedUriPermissions");
7943        Preconditions.checkNotNull(packageName, "packageName");
7944
7945        final int callingUid = Binder.getCallingUid();
7946        final IPackageManager pm = AppGlobals.getPackageManager();
7947        try {
7948            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7949            if (packageUid != callingUid) {
7950                throw new SecurityException(
7951                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7952            }
7953        } catch (RemoteException e) {
7954            throw new SecurityException("Failed to verify package name ownership");
7955        }
7956
7957        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7958        synchronized (this) {
7959            if (incoming) {
7960                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7961                        callingUid);
7962                if (perms == null) {
7963                    Slog.w(TAG, "No permission grants found for " + packageName);
7964                } else {
7965                    for (UriPermission perm : perms.values()) {
7966                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7967                            result.add(perm.buildPersistedPublicApiObject());
7968                        }
7969                    }
7970                }
7971            } else {
7972                final int size = mGrantedUriPermissions.size();
7973                for (int i = 0; i < size; i++) {
7974                    final ArrayMap<GrantUri, UriPermission> perms =
7975                            mGrantedUriPermissions.valueAt(i);
7976                    for (UriPermission perm : perms.values()) {
7977                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7978                            result.add(perm.buildPersistedPublicApiObject());
7979                        }
7980                    }
7981                }
7982            }
7983        }
7984        return new ParceledListSlice<android.content.UriPermission>(result);
7985    }
7986
7987    @Override
7988    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7989        synchronized (this) {
7990            ProcessRecord app =
7991                who != null ? getRecordForAppLocked(who) : null;
7992            if (app == null) return;
7993
7994            Message msg = Message.obtain();
7995            msg.what = WAIT_FOR_DEBUGGER_MSG;
7996            msg.obj = app;
7997            msg.arg1 = waiting ? 1 : 0;
7998            mHandler.sendMessage(msg);
7999        }
8000    }
8001
8002    @Override
8003    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8004        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8005        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8006        outInfo.availMem = Process.getFreeMemory();
8007        outInfo.totalMem = Process.getTotalMemory();
8008        outInfo.threshold = homeAppMem;
8009        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8010        outInfo.hiddenAppThreshold = cachedAppMem;
8011        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8012                ProcessList.SERVICE_ADJ);
8013        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8014                ProcessList.VISIBLE_APP_ADJ);
8015        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8016                ProcessList.FOREGROUND_APP_ADJ);
8017    }
8018
8019    // =========================================================
8020    // TASK MANAGEMENT
8021    // =========================================================
8022
8023    @Override
8024    public List<IAppTask> getAppTasks(String callingPackage) {
8025        int callingUid = Binder.getCallingUid();
8026        long ident = Binder.clearCallingIdentity();
8027
8028        synchronized(this) {
8029            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8030            try {
8031                if (localLOGV) Slog.v(TAG, "getAppTasks");
8032
8033                final int N = mRecentTasks.size();
8034                for (int i = 0; i < N; i++) {
8035                    TaskRecord tr = mRecentTasks.get(i);
8036                    // Skip tasks that do not match the caller.  We don't need to verify
8037                    // callingPackage, because we are also limiting to callingUid and know
8038                    // that will limit to the correct security sandbox.
8039                    if (tr.effectiveUid != callingUid) {
8040                        continue;
8041                    }
8042                    Intent intent = tr.getBaseIntent();
8043                    if (intent == null ||
8044                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8045                        continue;
8046                    }
8047                    ActivityManager.RecentTaskInfo taskInfo =
8048                            createRecentTaskInfoFromTaskRecord(tr);
8049                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8050                    list.add(taskImpl);
8051                }
8052            } finally {
8053                Binder.restoreCallingIdentity(ident);
8054            }
8055            return list;
8056        }
8057    }
8058
8059    @Override
8060    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8061        final int callingUid = Binder.getCallingUid();
8062        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8063
8064        synchronized(this) {
8065            if (localLOGV) Slog.v(
8066                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8067
8068            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8069                    callingUid);
8070
8071            // TODO: Improve with MRU list from all ActivityStacks.
8072            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8073        }
8074
8075        return list;
8076    }
8077
8078    /**
8079     * Creates a new RecentTaskInfo from a TaskRecord.
8080     */
8081    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8082        // Update the task description to reflect any changes in the task stack
8083        tr.updateTaskDescription();
8084
8085        // Compose the recent task info
8086        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8087        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8088        rti.persistentId = tr.taskId;
8089        rti.baseIntent = new Intent(tr.getBaseIntent());
8090        rti.origActivity = tr.origActivity;
8091        rti.description = tr.lastDescription;
8092        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8093        rti.userId = tr.userId;
8094        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8095        rti.firstActiveTime = tr.firstActiveTime;
8096        rti.lastActiveTime = tr.lastActiveTime;
8097        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8098        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8099        return rti;
8100    }
8101
8102    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8103        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8104                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8105        if (!allowed) {
8106            if (checkPermission(android.Manifest.permission.GET_TASKS,
8107                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8108                // Temporary compatibility: some existing apps on the system image may
8109                // still be requesting the old permission and not switched to the new
8110                // one; if so, we'll still allow them full access.  This means we need
8111                // to see if they are holding the old permission and are a system app.
8112                try {
8113                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8114                        allowed = true;
8115                        Slog.w(TAG, caller + ": caller " + callingUid
8116                                + " is using old GET_TASKS but privileged; allowing");
8117                    }
8118                } catch (RemoteException e) {
8119                }
8120            }
8121        }
8122        if (!allowed) {
8123            Slog.w(TAG, caller + ": caller " + callingUid
8124                    + " does not hold GET_TASKS; limiting output");
8125        }
8126        return allowed;
8127    }
8128
8129    @Override
8130    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8131        final int callingUid = Binder.getCallingUid();
8132        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8133                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8134
8135        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8136        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8137        synchronized (this) {
8138            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8139                    callingUid);
8140            final boolean detailed = checkCallingPermission(
8141                    android.Manifest.permission.GET_DETAILED_TASKS)
8142                    == PackageManager.PERMISSION_GRANTED;
8143
8144            final int N = mRecentTasks.size();
8145            ArrayList<ActivityManager.RecentTaskInfo> res
8146                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8147                            maxNum < N ? maxNum : N);
8148
8149            final Set<Integer> includedUsers;
8150            if (includeProfiles) {
8151                includedUsers = getProfileIdsLocked(userId);
8152            } else {
8153                includedUsers = new HashSet<Integer>();
8154            }
8155            includedUsers.add(Integer.valueOf(userId));
8156
8157            for (int i=0; i<N && maxNum > 0; i++) {
8158                TaskRecord tr = mRecentTasks.get(i);
8159                // Only add calling user or related users recent tasks
8160                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8161                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8162                    continue;
8163                }
8164
8165                // Return the entry if desired by the caller.  We always return
8166                // the first entry, because callers always expect this to be the
8167                // foreground app.  We may filter others if the caller has
8168                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8169                // we should exclude the entry.
8170
8171                if (i == 0
8172                        || withExcluded
8173                        || (tr.intent == null)
8174                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8175                                == 0)) {
8176                    if (!allowed) {
8177                        // If the caller doesn't have the GET_TASKS permission, then only
8178                        // allow them to see a small subset of tasks -- their own and home.
8179                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8180                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8181                            continue;
8182                        }
8183                    }
8184                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8185                        if (tr.stack != null && tr.stack.isHomeStack()) {
8186                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8187                            continue;
8188                        }
8189                    }
8190                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8191                        // Don't include auto remove tasks that are finished or finishing.
8192                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8193                                + tr);
8194                        continue;
8195                    }
8196                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8197                            && !tr.isAvailable) {
8198                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8199                        continue;
8200                    }
8201
8202                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8203                    if (!detailed) {
8204                        rti.baseIntent.replaceExtras((Bundle)null);
8205                    }
8206
8207                    res.add(rti);
8208                    maxNum--;
8209                }
8210            }
8211            return res;
8212        }
8213    }
8214
8215    TaskRecord recentTaskForIdLocked(int id) {
8216        final int N = mRecentTasks.size();
8217            for (int i=0; i<N; i++) {
8218                TaskRecord tr = mRecentTasks.get(i);
8219                if (tr.taskId == id) {
8220                    return tr;
8221                }
8222            }
8223            return null;
8224    }
8225
8226    @Override
8227    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8228        synchronized (this) {
8229            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8230                    "getTaskThumbnail()");
8231            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8232            if (tr != null) {
8233                return tr.getTaskThumbnailLocked();
8234            }
8235        }
8236        return null;
8237    }
8238
8239    @Override
8240    public int addAppTask(IBinder activityToken, Intent intent,
8241            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8242        final int callingUid = Binder.getCallingUid();
8243        final long callingIdent = Binder.clearCallingIdentity();
8244
8245        try {
8246            synchronized (this) {
8247                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8248                if (r == null) {
8249                    throw new IllegalArgumentException("Activity does not exist; token="
8250                            + activityToken);
8251                }
8252                ComponentName comp = intent.getComponent();
8253                if (comp == null) {
8254                    throw new IllegalArgumentException("Intent " + intent
8255                            + " must specify explicit component");
8256                }
8257                if (thumbnail.getWidth() != mThumbnailWidth
8258                        || thumbnail.getHeight() != mThumbnailHeight) {
8259                    throw new IllegalArgumentException("Bad thumbnail size: got "
8260                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8261                            + mThumbnailWidth + "x" + mThumbnailHeight);
8262                }
8263                if (intent.getSelector() != null) {
8264                    intent.setSelector(null);
8265                }
8266                if (intent.getSourceBounds() != null) {
8267                    intent.setSourceBounds(null);
8268                }
8269                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8270                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8271                        // The caller has added this as an auto-remove task...  that makes no
8272                        // sense, so turn off auto-remove.
8273                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8274                    }
8275                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8276                    // Must be a new task.
8277                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8278                }
8279                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8280                    mLastAddedTaskActivity = null;
8281                }
8282                ActivityInfo ainfo = mLastAddedTaskActivity;
8283                if (ainfo == null) {
8284                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8285                            comp, 0, UserHandle.getUserId(callingUid));
8286                    if (ainfo.applicationInfo.uid != callingUid) {
8287                        throw new SecurityException(
8288                                "Can't add task for another application: target uid="
8289                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8290                    }
8291                }
8292
8293                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8294                        intent, description);
8295
8296                int trimIdx = trimRecentsForTaskLocked(task, false);
8297                if (trimIdx >= 0) {
8298                    // If this would have caused a trim, then we'll abort because that
8299                    // means it would be added at the end of the list but then just removed.
8300                    return INVALID_TASK_ID;
8301                }
8302
8303                final int N = mRecentTasks.size();
8304                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8305                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8306                    tr.removedFromRecents();
8307                }
8308
8309                task.inRecents = true;
8310                mRecentTasks.add(task);
8311                r.task.stack.addTask(task, false, false);
8312
8313                task.setLastThumbnail(thumbnail);
8314                task.freeLastThumbnail();
8315
8316                return task.taskId;
8317            }
8318        } finally {
8319            Binder.restoreCallingIdentity(callingIdent);
8320        }
8321    }
8322
8323    @Override
8324    public Point getAppTaskThumbnailSize() {
8325        synchronized (this) {
8326            return new Point(mThumbnailWidth,  mThumbnailHeight);
8327        }
8328    }
8329
8330    @Override
8331    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8332        synchronized (this) {
8333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8334            if (r != null) {
8335                r.setTaskDescription(td);
8336                r.task.updateTaskDescription();
8337            }
8338        }
8339    }
8340
8341    @Override
8342    public Bitmap getTaskDescriptionIcon(String filename) {
8343        if (!FileUtils.isValidExtFilename(filename)
8344                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8345            throw new IllegalArgumentException("Bad filename: " + filename);
8346        }
8347        return mTaskPersister.getTaskDescriptionIcon(filename);
8348    }
8349
8350    @Override
8351    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8352            throws RemoteException {
8353        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8354                opts.getCustomInPlaceResId() == 0) {
8355            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8356                    "with valid animation");
8357        }
8358        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8359        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8360                opts.getCustomInPlaceResId());
8361        mWindowManager.executeAppTransition();
8362    }
8363
8364    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8365        mRecentTasks.remove(tr);
8366        tr.removedFromRecents();
8367        ComponentName component = tr.getBaseIntent().getComponent();
8368        if (component == null) {
8369            Slog.w(TAG, "No component for base intent of task: " + tr);
8370            return;
8371        }
8372
8373        if (!killProcess) {
8374            return;
8375        }
8376
8377        // Determine if the process(es) for this task should be killed.
8378        final String pkg = component.getPackageName();
8379        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8380        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8381        for (int i = 0; i < pmap.size(); i++) {
8382
8383            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8384            for (int j = 0; j < uids.size(); j++) {
8385                ProcessRecord proc = uids.valueAt(j);
8386                if (proc.userId != tr.userId) {
8387                    // Don't kill process for a different user.
8388                    continue;
8389                }
8390                if (proc == mHomeProcess) {
8391                    // Don't kill the home process along with tasks from the same package.
8392                    continue;
8393                }
8394                if (!proc.pkgList.containsKey(pkg)) {
8395                    // Don't kill process that is not associated with this task.
8396                    continue;
8397                }
8398
8399                for (int k = 0; k < proc.activities.size(); k++) {
8400                    TaskRecord otherTask = proc.activities.get(k).task;
8401                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8402                        // Don't kill process(es) that has an activity in a different task that is
8403                        // also in recents.
8404                        return;
8405                    }
8406                }
8407
8408                // Add process to kill list.
8409                procsToKill.add(proc);
8410            }
8411        }
8412
8413        // Find any running services associated with this app and stop if needed.
8414        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8415
8416        // Kill the running processes.
8417        for (int i = 0; i < procsToKill.size(); i++) {
8418            ProcessRecord pr = procsToKill.get(i);
8419            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8420                pr.kill("remove task", true);
8421            } else {
8422                pr.waitingToKill = "remove task";
8423            }
8424        }
8425    }
8426
8427    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8428        // Remove all tasks with activities in the specified package from the list of recent tasks
8429        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8430            TaskRecord tr = mRecentTasks.get(i);
8431            if (tr.userId != userId) continue;
8432
8433            ComponentName cn = tr.intent.getComponent();
8434            if (cn != null && cn.getPackageName().equals(packageName)) {
8435                // If the package name matches, remove the task.
8436                removeTaskByIdLocked(tr.taskId, true);
8437            }
8438        }
8439    }
8440
8441    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8442        final IPackageManager pm = AppGlobals.getPackageManager();
8443        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8444
8445        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8446            TaskRecord tr = mRecentTasks.get(i);
8447            if (tr.userId != userId) continue;
8448
8449            ComponentName cn = tr.intent.getComponent();
8450            if (cn != null && cn.getPackageName().equals(packageName)) {
8451                // Skip if component still exists in the package.
8452                if (componentsKnownToExist.contains(cn)) continue;
8453
8454                try {
8455                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8456                    if (info != null) {
8457                        componentsKnownToExist.add(cn);
8458                    } else {
8459                        removeTaskByIdLocked(tr.taskId, false);
8460                    }
8461                } catch (RemoteException e) {
8462                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8463                }
8464            }
8465        }
8466    }
8467
8468    /**
8469     * Removes the task with the specified task id.
8470     *
8471     * @param taskId Identifier of the task to be removed.
8472     * @param killProcess Kill any process associated with the task if possible.
8473     * @return Returns true if the given task was found and removed.
8474     */
8475    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8476        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8477        if (tr != null) {
8478            tr.removeTaskActivitiesLocked();
8479            cleanUpRemovedTaskLocked(tr, killProcess);
8480            if (tr.isPersistable) {
8481                notifyTaskPersisterLocked(null, true);
8482            }
8483            return true;
8484        }
8485        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8486        return false;
8487    }
8488
8489    @Override
8490    public boolean removeTask(int taskId) {
8491        synchronized (this) {
8492            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8493                    "removeTask()");
8494            long ident = Binder.clearCallingIdentity();
8495            try {
8496                return removeTaskByIdLocked(taskId, true);
8497            } finally {
8498                Binder.restoreCallingIdentity(ident);
8499            }
8500        }
8501    }
8502
8503    /**
8504     * TODO: Add mController hook
8505     */
8506    @Override
8507    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8508        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8509                "moveTaskToFront()");
8510
8511        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8512        synchronized(this) {
8513            moveTaskToFrontLocked(taskId, flags, options);
8514        }
8515    }
8516
8517    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8518        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8519                Binder.getCallingUid(), -1, -1, "Task to front")) {
8520            ActivityOptions.abort(options);
8521            return;
8522        }
8523        final long origId = Binder.clearCallingIdentity();
8524        try {
8525            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8526            if (task == null) {
8527                Slog.d(TAG, "Could not find task for id: "+ taskId);
8528                return;
8529            }
8530            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8531                mStackSupervisor.showLockTaskToast();
8532                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8533                return;
8534            }
8535            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8536            if (prev != null && prev.isRecentsActivity()) {
8537                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8538            }
8539            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8540        } finally {
8541            Binder.restoreCallingIdentity(origId);
8542        }
8543        ActivityOptions.abort(options);
8544    }
8545
8546    @Override
8547    public void moveTaskToBack(int taskId) {
8548        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8549                "moveTaskToBack()");
8550
8551        synchronized(this) {
8552            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8553            if (tr != null) {
8554                if (tr == mStackSupervisor.mLockTaskModeTask) {
8555                    mStackSupervisor.showLockTaskToast();
8556                    return;
8557                }
8558                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8559                ActivityStack stack = tr.stack;
8560                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8561                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8562                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8563                        return;
8564                    }
8565                }
8566                final long origId = Binder.clearCallingIdentity();
8567                try {
8568                    stack.moveTaskToBackLocked(taskId);
8569                } finally {
8570                    Binder.restoreCallingIdentity(origId);
8571                }
8572            }
8573        }
8574    }
8575
8576    /**
8577     * Moves an activity, and all of the other activities within the same task, to the bottom
8578     * of the history stack.  The activity's order within the task is unchanged.
8579     *
8580     * @param token A reference to the activity we wish to move
8581     * @param nonRoot If false then this only works if the activity is the root
8582     *                of a task; if true it will work for any activity in a task.
8583     * @return Returns true if the move completed, false if not.
8584     */
8585    @Override
8586    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8587        enforceNotIsolatedCaller("moveActivityTaskToBack");
8588        synchronized(this) {
8589            final long origId = Binder.clearCallingIdentity();
8590            try {
8591                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8592                if (taskId >= 0) {
8593                    if ((mStackSupervisor.mLockTaskModeTask != null)
8594                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8595                        mStackSupervisor.showLockTaskToast();
8596                        return false;
8597                    }
8598                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8599                }
8600            } finally {
8601                Binder.restoreCallingIdentity(origId);
8602            }
8603        }
8604        return false;
8605    }
8606
8607    @Override
8608    public void moveTaskBackwards(int task) {
8609        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8610                "moveTaskBackwards()");
8611
8612        synchronized(this) {
8613            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8614                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8615                return;
8616            }
8617            final long origId = Binder.clearCallingIdentity();
8618            moveTaskBackwardsLocked(task);
8619            Binder.restoreCallingIdentity(origId);
8620        }
8621    }
8622
8623    private final void moveTaskBackwardsLocked(int task) {
8624        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8625    }
8626
8627    @Override
8628    public IBinder getHomeActivityToken() throws RemoteException {
8629        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8630                "getHomeActivityToken()");
8631        synchronized (this) {
8632            return mStackSupervisor.getHomeActivityToken();
8633        }
8634    }
8635
8636    @Override
8637    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8638            IActivityContainerCallback callback) throws RemoteException {
8639        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8640                "createActivityContainer()");
8641        synchronized (this) {
8642            if (parentActivityToken == null) {
8643                throw new IllegalArgumentException("parent token must not be null");
8644            }
8645            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8646            if (r == null) {
8647                return null;
8648            }
8649            if (callback == null) {
8650                throw new IllegalArgumentException("callback must not be null");
8651            }
8652            return mStackSupervisor.createActivityContainer(r, callback);
8653        }
8654    }
8655
8656    @Override
8657    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "deleteActivityContainer()");
8660        synchronized (this) {
8661            mStackSupervisor.deleteActivityContainer(container);
8662        }
8663    }
8664
8665    @Override
8666    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8667            throws RemoteException {
8668        synchronized (this) {
8669            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8670            if (stack != null) {
8671                return stack.mActivityContainer;
8672            }
8673            return null;
8674        }
8675    }
8676
8677    @Override
8678    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8679        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8680                "moveTaskToStack()");
8681        if (stackId == HOME_STACK_ID) {
8682            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8683                    new RuntimeException("here").fillInStackTrace());
8684        }
8685        synchronized (this) {
8686            long ident = Binder.clearCallingIdentity();
8687            try {
8688                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8689                        + stackId + " toTop=" + toTop);
8690                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8691            } finally {
8692                Binder.restoreCallingIdentity(ident);
8693            }
8694        }
8695    }
8696
8697    @Override
8698    public void resizeStack(int stackBoxId, Rect bounds) {
8699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8700                "resizeStackBox()");
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            mWindowManager.resizeStack(stackBoxId, bounds);
8704        } finally {
8705            Binder.restoreCallingIdentity(ident);
8706        }
8707    }
8708
8709    @Override
8710    public List<StackInfo> getAllStackInfos() {
8711        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8712                "getAllStackInfos()");
8713        long ident = Binder.clearCallingIdentity();
8714        try {
8715            synchronized (this) {
8716                return mStackSupervisor.getAllStackInfosLocked();
8717            }
8718        } finally {
8719            Binder.restoreCallingIdentity(ident);
8720        }
8721    }
8722
8723    @Override
8724    public StackInfo getStackInfo(int stackId) {
8725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8726                "getStackInfo()");
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            synchronized (this) {
8730                return mStackSupervisor.getStackInfoLocked(stackId);
8731            }
8732        } finally {
8733            Binder.restoreCallingIdentity(ident);
8734        }
8735    }
8736
8737    @Override
8738    public boolean isInHomeStack(int taskId) {
8739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8740                "getStackInfo()");
8741        long ident = Binder.clearCallingIdentity();
8742        try {
8743            synchronized (this) {
8744                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8745                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8746            }
8747        } finally {
8748            Binder.restoreCallingIdentity(ident);
8749        }
8750    }
8751
8752    @Override
8753    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8754        synchronized(this) {
8755            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8756        }
8757    }
8758
8759    private boolean isLockTaskAuthorized(String pkg) {
8760        final DevicePolicyManager dpm = (DevicePolicyManager)
8761                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8762        try {
8763            int uid = mContext.getPackageManager().getPackageUid(pkg,
8764                    Binder.getCallingUserHandle().getIdentifier());
8765            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8766        } catch (NameNotFoundException e) {
8767            return false;
8768        }
8769    }
8770
8771    void startLockTaskMode(TaskRecord task) {
8772        final String pkg;
8773        synchronized (this) {
8774            pkg = task.intent.getComponent().getPackageName();
8775        }
8776        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8777        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8778            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8779                    StatusBarManagerInternal.class);
8780            if (statusBarManager != null) {
8781                statusBarManager.showScreenPinningRequest();
8782            }
8783            return;
8784        }
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                // Since we lost lock on task, make sure it is still there.
8789                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8790                if (task != null) {
8791                    if (!isSystemInitiated
8792                            && ((mStackSupervisor.getFocusedStack() == null)
8793                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8794                        throw new IllegalArgumentException("Invalid task, not in foreground");
8795                    }
8796                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8797                            "startLockTask");
8798                }
8799            }
8800        } finally {
8801            Binder.restoreCallingIdentity(ident);
8802        }
8803    }
8804
8805    @Override
8806    public void startLockTaskMode(int taskId) {
8807        final TaskRecord task;
8808        long ident = Binder.clearCallingIdentity();
8809        try {
8810            synchronized (this) {
8811                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8812            }
8813        } finally {
8814            Binder.restoreCallingIdentity(ident);
8815        }
8816        if (task != null) {
8817            startLockTaskMode(task);
8818        }
8819    }
8820
8821    @Override
8822    public void startLockTaskMode(IBinder token) {
8823        final TaskRecord task;
8824        long ident = Binder.clearCallingIdentity();
8825        try {
8826            synchronized (this) {
8827                final ActivityRecord r = ActivityRecord.forToken(token);
8828                if (r == null) {
8829                    return;
8830                }
8831                task = r.task;
8832            }
8833        } finally {
8834            Binder.restoreCallingIdentity(ident);
8835        }
8836        if (task != null) {
8837            startLockTaskMode(task);
8838        }
8839    }
8840
8841    @Override
8842    public void startLockTaskModeOnCurrent() throws RemoteException {
8843        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8844                "startLockTaskModeOnCurrent");
8845        long ident = Binder.clearCallingIdentity();
8846        try {
8847            ActivityRecord r = null;
8848            synchronized (this) {
8849                r = mStackSupervisor.topRunningActivityLocked();
8850            }
8851            startLockTaskMode(r.task);
8852        } finally {
8853            Binder.restoreCallingIdentity(ident);
8854        }
8855    }
8856
8857    @Override
8858    public void stopLockTaskMode() {
8859        // Verify that the user matches the package of the intent for the TaskRecord
8860        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8861        // and stopLockTaskMode.
8862        final int callingUid = Binder.getCallingUid();
8863        if (callingUid != Process.SYSTEM_UID) {
8864            try {
8865                String pkg =
8866                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8867                int uid = mContext.getPackageManager().getPackageUid(pkg,
8868                        Binder.getCallingUserHandle().getIdentifier());
8869                if (uid != callingUid) {
8870                    throw new SecurityException("Invalid uid, expected " + uid);
8871                }
8872            } catch (NameNotFoundException e) {
8873                Log.d(TAG, "stopLockTaskMode " + e);
8874                return;
8875            }
8876        }
8877        long ident = Binder.clearCallingIdentity();
8878        try {
8879            Log.d(TAG, "stopLockTaskMode");
8880            // Stop lock task
8881            synchronized (this) {
8882                mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8883            }
8884        } finally {
8885            Binder.restoreCallingIdentity(ident);
8886        }
8887    }
8888
8889    @Override
8890    public void stopLockTaskModeOnCurrent() throws RemoteException {
8891        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8892                "stopLockTaskModeOnCurrent");
8893        long ident = Binder.clearCallingIdentity();
8894        try {
8895            stopLockTaskMode();
8896        } finally {
8897            Binder.restoreCallingIdentity(ident);
8898        }
8899    }
8900
8901    @Override
8902    public boolean isInLockTaskMode() {
8903        synchronized (this) {
8904            return mStackSupervisor.isInLockTaskMode();
8905        }
8906    }
8907
8908    // =========================================================
8909    // CONTENT PROVIDERS
8910    // =========================================================
8911
8912    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8913        List<ProviderInfo> providers = null;
8914        try {
8915            providers = AppGlobals.getPackageManager().
8916                queryContentProviders(app.processName, app.uid,
8917                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8918        } catch (RemoteException ex) {
8919        }
8920        if (DEBUG_MU)
8921            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8922        int userId = app.userId;
8923        if (providers != null) {
8924            int N = providers.size();
8925            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8926            for (int i=0; i<N; i++) {
8927                ProviderInfo cpi =
8928                    (ProviderInfo)providers.get(i);
8929                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8930                        cpi.name, cpi.flags);
8931                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8932                    // This is a singleton provider, but a user besides the
8933                    // default user is asking to initialize a process it runs
8934                    // in...  well, no, it doesn't actually run in this process,
8935                    // it runs in the process of the default user.  Get rid of it.
8936                    providers.remove(i);
8937                    N--;
8938                    i--;
8939                    continue;
8940                }
8941
8942                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8943                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8944                if (cpr == null) {
8945                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8946                    mProviderMap.putProviderByClass(comp, cpr);
8947                }
8948                if (DEBUG_MU)
8949                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8950                app.pubProviders.put(cpi.name, cpr);
8951                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8952                    // Don't add this if it is a platform component that is marked
8953                    // to run in multiple processes, because this is actually
8954                    // part of the framework so doesn't make sense to track as a
8955                    // separate apk in the process.
8956                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8957                            mProcessStats);
8958                }
8959                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8960            }
8961        }
8962        return providers;
8963    }
8964
8965    /**
8966     * Check if {@link ProcessRecord} has a possible chance at accessing the
8967     * given {@link ProviderInfo}. Final permission checking is always done
8968     * in {@link ContentProvider}.
8969     */
8970    private final String checkContentProviderPermissionLocked(
8971            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8972        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8973        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8974        boolean checkedGrants = false;
8975        if (checkUser) {
8976            // Looking for cross-user grants before enforcing the typical cross-users permissions
8977            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8978            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8979                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8980                    return null;
8981                }
8982                checkedGrants = true;
8983            }
8984            userId = handleIncomingUser(callingPid, callingUid, userId,
8985                    false, ALLOW_NON_FULL,
8986                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8987            if (userId != tmpTargetUserId) {
8988                // When we actually went to determine the final targer user ID, this ended
8989                // up different than our initial check for the authority.  This is because
8990                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8991                // SELF.  So we need to re-check the grants again.
8992                checkedGrants = false;
8993            }
8994        }
8995        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8996                cpi.applicationInfo.uid, cpi.exported)
8997                == PackageManager.PERMISSION_GRANTED) {
8998            return null;
8999        }
9000        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9001                cpi.applicationInfo.uid, cpi.exported)
9002                == PackageManager.PERMISSION_GRANTED) {
9003            return null;
9004        }
9005
9006        PathPermission[] pps = cpi.pathPermissions;
9007        if (pps != null) {
9008            int i = pps.length;
9009            while (i > 0) {
9010                i--;
9011                PathPermission pp = pps[i];
9012                String pprperm = pp.getReadPermission();
9013                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9014                        cpi.applicationInfo.uid, cpi.exported)
9015                        == PackageManager.PERMISSION_GRANTED) {
9016                    return null;
9017                }
9018                String ppwperm = pp.getWritePermission();
9019                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9020                        cpi.applicationInfo.uid, cpi.exported)
9021                        == PackageManager.PERMISSION_GRANTED) {
9022                    return null;
9023                }
9024            }
9025        }
9026        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9027            return null;
9028        }
9029
9030        String msg;
9031        if (!cpi.exported) {
9032            msg = "Permission Denial: opening provider " + cpi.name
9033                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9034                    + ", uid=" + callingUid + ") that is not exported from uid "
9035                    + cpi.applicationInfo.uid;
9036        } else {
9037            msg = "Permission Denial: opening provider " + cpi.name
9038                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9039                    + ", uid=" + callingUid + ") requires "
9040                    + cpi.readPermission + " or " + cpi.writePermission;
9041        }
9042        Slog.w(TAG, msg);
9043        return msg;
9044    }
9045
9046    /**
9047     * Returns if the ContentProvider has granted a uri to callingUid
9048     */
9049    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9050        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9051        if (perms != null) {
9052            for (int i=perms.size()-1; i>=0; i--) {
9053                GrantUri grantUri = perms.keyAt(i);
9054                if (grantUri.sourceUserId == userId || !checkUser) {
9055                    if (matchesProvider(grantUri.uri, cpi)) {
9056                        return true;
9057                    }
9058                }
9059            }
9060        }
9061        return false;
9062    }
9063
9064    /**
9065     * Returns true if the uri authority is one of the authorities specified in the provider.
9066     */
9067    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9068        String uriAuth = uri.getAuthority();
9069        String cpiAuth = cpi.authority;
9070        if (cpiAuth.indexOf(';') == -1) {
9071            return cpiAuth.equals(uriAuth);
9072        }
9073        String[] cpiAuths = cpiAuth.split(";");
9074        int length = cpiAuths.length;
9075        for (int i = 0; i < length; i++) {
9076            if (cpiAuths[i].equals(uriAuth)) return true;
9077        }
9078        return false;
9079    }
9080
9081    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9082            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9083        if (r != null) {
9084            for (int i=0; i<r.conProviders.size(); i++) {
9085                ContentProviderConnection conn = r.conProviders.get(i);
9086                if (conn.provider == cpr) {
9087                    if (DEBUG_PROVIDER) Slog.v(TAG,
9088                            "Adding provider requested by "
9089                            + r.processName + " from process "
9090                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9091                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9092                    if (stable) {
9093                        conn.stableCount++;
9094                        conn.numStableIncs++;
9095                    } else {
9096                        conn.unstableCount++;
9097                        conn.numUnstableIncs++;
9098                    }
9099                    return conn;
9100                }
9101            }
9102            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9103            if (stable) {
9104                conn.stableCount = 1;
9105                conn.numStableIncs = 1;
9106            } else {
9107                conn.unstableCount = 1;
9108                conn.numUnstableIncs = 1;
9109            }
9110            cpr.connections.add(conn);
9111            r.conProviders.add(conn);
9112            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9113            return conn;
9114        }
9115        cpr.addExternalProcessHandleLocked(externalProcessToken);
9116        return null;
9117    }
9118
9119    boolean decProviderCountLocked(ContentProviderConnection conn,
9120            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9121        if (conn != null) {
9122            cpr = conn.provider;
9123            if (DEBUG_PROVIDER) Slog.v(TAG,
9124                    "Removing provider requested by "
9125                    + conn.client.processName + " from process "
9126                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9127                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9128            if (stable) {
9129                conn.stableCount--;
9130            } else {
9131                conn.unstableCount--;
9132            }
9133            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9134                cpr.connections.remove(conn);
9135                conn.client.conProviders.remove(conn);
9136                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9137                return true;
9138            }
9139            return false;
9140        }
9141        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9142        return false;
9143    }
9144
9145    private void checkTime(long startTime, String where) {
9146        long now = SystemClock.elapsedRealtime();
9147        if ((now-startTime) > 1000) {
9148            // If we are taking more than a second, log about it.
9149            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9150        }
9151    }
9152
9153    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9154            String name, IBinder token, boolean stable, int userId) {
9155        ContentProviderRecord cpr;
9156        ContentProviderConnection conn = null;
9157        ProviderInfo cpi = null;
9158
9159        synchronized(this) {
9160            long startTime = SystemClock.elapsedRealtime();
9161
9162            ProcessRecord r = null;
9163            if (caller != null) {
9164                r = getRecordForAppLocked(caller);
9165                if (r == null) {
9166                    throw new SecurityException(
9167                            "Unable to find app for caller " + caller
9168                          + " (pid=" + Binder.getCallingPid()
9169                          + ") when getting content provider " + name);
9170                }
9171            }
9172
9173            boolean checkCrossUser = true;
9174
9175            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9176
9177            // First check if this content provider has been published...
9178            cpr = mProviderMap.getProviderByName(name, userId);
9179            // If that didn't work, check if it exists for user 0 and then
9180            // verify that it's a singleton provider before using it.
9181            if (cpr == null && userId != UserHandle.USER_OWNER) {
9182                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9183                if (cpr != null) {
9184                    cpi = cpr.info;
9185                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9186                            cpi.name, cpi.flags)
9187                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9188                        userId = UserHandle.USER_OWNER;
9189                        checkCrossUser = false;
9190                    } else {
9191                        cpr = null;
9192                        cpi = null;
9193                    }
9194                }
9195            }
9196
9197            boolean providerRunning = cpr != null;
9198            if (providerRunning) {
9199                cpi = cpr.info;
9200                String msg;
9201                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9202                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9203                        != null) {
9204                    throw new SecurityException(msg);
9205                }
9206                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9207
9208                if (r != null && cpr.canRunHere(r)) {
9209                    // This provider has been published or is in the process
9210                    // of being published...  but it is also allowed to run
9211                    // in the caller's process, so don't make a connection
9212                    // and just let the caller instantiate its own instance.
9213                    ContentProviderHolder holder = cpr.newHolder(null);
9214                    // don't give caller the provider object, it needs
9215                    // to make its own.
9216                    holder.provider = null;
9217                    return holder;
9218                }
9219
9220                final long origId = Binder.clearCallingIdentity();
9221
9222                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9223
9224                // In this case the provider instance already exists, so we can
9225                // return it right away.
9226                conn = incProviderCountLocked(r, cpr, token, stable);
9227                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9228                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9229                        // If this is a perceptible app accessing the provider,
9230                        // make sure to count it as being accessed and thus
9231                        // back up on the LRU list.  This is good because
9232                        // content providers are often expensive to start.
9233                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9234                        updateLruProcessLocked(cpr.proc, false, null);
9235                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9236                    }
9237                }
9238
9239                if (cpr.proc != null) {
9240                    if (false) {
9241                        if (cpr.name.flattenToShortString().equals(
9242                                "com.android.providers.calendar/.CalendarProvider2")) {
9243                            Slog.v(TAG, "****************** KILLING "
9244                                + cpr.name.flattenToShortString());
9245                            Process.killProcess(cpr.proc.pid);
9246                        }
9247                    }
9248                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9249                    boolean success = updateOomAdjLocked(cpr.proc);
9250                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9251                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9252                    // NOTE: there is still a race here where a signal could be
9253                    // pending on the process even though we managed to update its
9254                    // adj level.  Not sure what to do about this, but at least
9255                    // the race is now smaller.
9256                    if (!success) {
9257                        // Uh oh...  it looks like the provider's process
9258                        // has been killed on us.  We need to wait for a new
9259                        // process to be started, and make sure its death
9260                        // doesn't kill our process.
9261                        Slog.i(TAG,
9262                                "Existing provider " + cpr.name.flattenToShortString()
9263                                + " is crashing; detaching " + r);
9264                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9265                        checkTime(startTime, "getContentProviderImpl: before appDied");
9266                        appDiedLocked(cpr.proc);
9267                        checkTime(startTime, "getContentProviderImpl: after appDied");
9268                        if (!lastRef) {
9269                            // This wasn't the last ref our process had on
9270                            // the provider...  we have now been killed, bail.
9271                            return null;
9272                        }
9273                        providerRunning = false;
9274                        conn = null;
9275                    }
9276                }
9277
9278                Binder.restoreCallingIdentity(origId);
9279            }
9280
9281            boolean singleton;
9282            if (!providerRunning) {
9283                try {
9284                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9285                    cpi = AppGlobals.getPackageManager().
9286                        resolveContentProvider(name,
9287                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9288                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9289                } catch (RemoteException ex) {
9290                }
9291                if (cpi == null) {
9292                    return null;
9293                }
9294                // If the provider is a singleton AND
9295                // (it's a call within the same user || the provider is a
9296                // privileged app)
9297                // Then allow connecting to the singleton provider
9298                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9299                        cpi.name, cpi.flags)
9300                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9301                if (singleton) {
9302                    userId = UserHandle.USER_OWNER;
9303                }
9304                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9305                checkTime(startTime, "getContentProviderImpl: got app info for user");
9306
9307                String msg;
9308                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9309                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9310                        != null) {
9311                    throw new SecurityException(msg);
9312                }
9313                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9314
9315                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9316                        && !cpi.processName.equals("system")) {
9317                    // If this content provider does not run in the system
9318                    // process, and the system is not yet ready to run other
9319                    // processes, then fail fast instead of hanging.
9320                    throw new IllegalArgumentException(
9321                            "Attempt to launch content provider before system ready");
9322                }
9323
9324                // Make sure that the user who owns this provider is running.  If not,
9325                // we don't want to allow it to run.
9326                if (!isUserRunningLocked(userId, false)) {
9327                    Slog.w(TAG, "Unable to launch app "
9328                            + cpi.applicationInfo.packageName + "/"
9329                            + cpi.applicationInfo.uid + " for provider "
9330                            + name + ": user " + userId + " is stopped");
9331                    return null;
9332                }
9333
9334                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9335                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9336                cpr = mProviderMap.getProviderByClass(comp, userId);
9337                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9338                final boolean firstClass = cpr == null;
9339                if (firstClass) {
9340                    final long ident = Binder.clearCallingIdentity();
9341                    try {
9342                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9343                        ApplicationInfo ai =
9344                            AppGlobals.getPackageManager().
9345                                getApplicationInfo(
9346                                        cpi.applicationInfo.packageName,
9347                                        STOCK_PM_FLAGS, userId);
9348                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9349                        if (ai == null) {
9350                            Slog.w(TAG, "No package info for content provider "
9351                                    + cpi.name);
9352                            return null;
9353                        }
9354                        ai = getAppInfoForUser(ai, userId);
9355                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9356                    } catch (RemoteException ex) {
9357                        // pm is in same process, this will never happen.
9358                    } finally {
9359                        Binder.restoreCallingIdentity(ident);
9360                    }
9361                }
9362
9363                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9364
9365                if (r != null && cpr.canRunHere(r)) {
9366                    // If this is a multiprocess provider, then just return its
9367                    // info and allow the caller to instantiate it.  Only do
9368                    // this if the provider is the same user as the caller's
9369                    // process, or can run as root (so can be in any process).
9370                    return cpr.newHolder(null);
9371                }
9372
9373                if (DEBUG_PROVIDER) {
9374                    RuntimeException e = new RuntimeException("here");
9375                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9376                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9377                }
9378
9379                // This is single process, and our app is now connecting to it.
9380                // See if we are already in the process of launching this
9381                // provider.
9382                final int N = mLaunchingProviders.size();
9383                int i;
9384                for (i=0; i<N; i++) {
9385                    if (mLaunchingProviders.get(i) == cpr) {
9386                        break;
9387                    }
9388                }
9389
9390                // If the provider is not already being launched, then get it
9391                // started.
9392                if (i >= N) {
9393                    final long origId = Binder.clearCallingIdentity();
9394
9395                    try {
9396                        // Content provider is now in use, its package can't be stopped.
9397                        try {
9398                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9399                            AppGlobals.getPackageManager().setPackageStoppedState(
9400                                    cpr.appInfo.packageName, false, userId);
9401                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9402                        } catch (RemoteException e) {
9403                        } catch (IllegalArgumentException e) {
9404                            Slog.w(TAG, "Failed trying to unstop package "
9405                                    + cpr.appInfo.packageName + ": " + e);
9406                        }
9407
9408                        // Use existing process if already started
9409                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9410                        ProcessRecord proc = getProcessRecordLocked(
9411                                cpi.processName, cpr.appInfo.uid, false);
9412                        if (proc != null && proc.thread != null) {
9413                            if (DEBUG_PROVIDER) {
9414                                Slog.d(TAG, "Installing in existing process " + proc);
9415                            }
9416                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9417                            proc.pubProviders.put(cpi.name, cpr);
9418                            try {
9419                                proc.thread.scheduleInstallProvider(cpi);
9420                            } catch (RemoteException e) {
9421                            }
9422                        } else {
9423                            checkTime(startTime, "getContentProviderImpl: before start process");
9424                            proc = startProcessLocked(cpi.processName,
9425                                    cpr.appInfo, false, 0, "content provider",
9426                                    new ComponentName(cpi.applicationInfo.packageName,
9427                                            cpi.name), false, false, false);
9428                            checkTime(startTime, "getContentProviderImpl: after start process");
9429                            if (proc == null) {
9430                                Slog.w(TAG, "Unable to launch app "
9431                                        + cpi.applicationInfo.packageName + "/"
9432                                        + cpi.applicationInfo.uid + " for provider "
9433                                        + name + ": process is bad");
9434                                return null;
9435                            }
9436                        }
9437                        cpr.launchingApp = proc;
9438                        mLaunchingProviders.add(cpr);
9439                    } finally {
9440                        Binder.restoreCallingIdentity(origId);
9441                    }
9442                }
9443
9444                checkTime(startTime, "getContentProviderImpl: updating data structures");
9445
9446                // Make sure the provider is published (the same provider class
9447                // may be published under multiple names).
9448                if (firstClass) {
9449                    mProviderMap.putProviderByClass(comp, cpr);
9450                }
9451
9452                mProviderMap.putProviderByName(name, cpr);
9453                conn = incProviderCountLocked(r, cpr, token, stable);
9454                if (conn != null) {
9455                    conn.waiting = true;
9456                }
9457            }
9458            checkTime(startTime, "getContentProviderImpl: done!");
9459        }
9460
9461        // Wait for the provider to be published...
9462        synchronized (cpr) {
9463            while (cpr.provider == null) {
9464                if (cpr.launchingApp == null) {
9465                    Slog.w(TAG, "Unable to launch app "
9466                            + cpi.applicationInfo.packageName + "/"
9467                            + cpi.applicationInfo.uid + " for provider "
9468                            + name + ": launching app became null");
9469                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9470                            UserHandle.getUserId(cpi.applicationInfo.uid),
9471                            cpi.applicationInfo.packageName,
9472                            cpi.applicationInfo.uid, name);
9473                    return null;
9474                }
9475                try {
9476                    if (DEBUG_MU) {
9477                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9478                                + cpr.launchingApp);
9479                    }
9480                    if (conn != null) {
9481                        conn.waiting = true;
9482                    }
9483                    cpr.wait();
9484                } catch (InterruptedException ex) {
9485                } finally {
9486                    if (conn != null) {
9487                        conn.waiting = false;
9488                    }
9489                }
9490            }
9491        }
9492        return cpr != null ? cpr.newHolder(conn) : null;
9493    }
9494
9495    @Override
9496    public final ContentProviderHolder getContentProvider(
9497            IApplicationThread caller, String name, int userId, boolean stable) {
9498        enforceNotIsolatedCaller("getContentProvider");
9499        if (caller == null) {
9500            String msg = "null IApplicationThread when getting content provider "
9501                    + name;
9502            Slog.w(TAG, msg);
9503            throw new SecurityException(msg);
9504        }
9505        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9506        // with cross-user grant.
9507        return getContentProviderImpl(caller, name, null, stable, userId);
9508    }
9509
9510    public ContentProviderHolder getContentProviderExternal(
9511            String name, int userId, IBinder token) {
9512        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9513            "Do not have permission in call getContentProviderExternal()");
9514        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9515                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9516        return getContentProviderExternalUnchecked(name, token, userId);
9517    }
9518
9519    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9520            IBinder token, int userId) {
9521        return getContentProviderImpl(null, name, token, true, userId);
9522    }
9523
9524    /**
9525     * Drop a content provider from a ProcessRecord's bookkeeping
9526     */
9527    public void removeContentProvider(IBinder connection, boolean stable) {
9528        enforceNotIsolatedCaller("removeContentProvider");
9529        long ident = Binder.clearCallingIdentity();
9530        try {
9531            synchronized (this) {
9532                ContentProviderConnection conn;
9533                try {
9534                    conn = (ContentProviderConnection)connection;
9535                } catch (ClassCastException e) {
9536                    String msg ="removeContentProvider: " + connection
9537                            + " not a ContentProviderConnection";
9538                    Slog.w(TAG, msg);
9539                    throw new IllegalArgumentException(msg);
9540                }
9541                if (conn == null) {
9542                    throw new NullPointerException("connection is null");
9543                }
9544                if (decProviderCountLocked(conn, null, null, stable)) {
9545                    updateOomAdjLocked();
9546                }
9547            }
9548        } finally {
9549            Binder.restoreCallingIdentity(ident);
9550        }
9551    }
9552
9553    public void removeContentProviderExternal(String name, IBinder token) {
9554        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9555            "Do not have permission in call removeContentProviderExternal()");
9556        int userId = UserHandle.getCallingUserId();
9557        long ident = Binder.clearCallingIdentity();
9558        try {
9559            removeContentProviderExternalUnchecked(name, token, userId);
9560        } finally {
9561            Binder.restoreCallingIdentity(ident);
9562        }
9563    }
9564
9565    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9566        synchronized (this) {
9567            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9568            if(cpr == null) {
9569                //remove from mProvidersByClass
9570                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9571                return;
9572            }
9573
9574            //update content provider record entry info
9575            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9576            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9577            if (localCpr.hasExternalProcessHandles()) {
9578                if (localCpr.removeExternalProcessHandleLocked(token)) {
9579                    updateOomAdjLocked();
9580                } else {
9581                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9582                            + " with no external reference for token: "
9583                            + token + ".");
9584                }
9585            } else {
9586                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9587                        + " with no external references.");
9588            }
9589        }
9590    }
9591
9592    public final void publishContentProviders(IApplicationThread caller,
9593            List<ContentProviderHolder> providers) {
9594        if (providers == null) {
9595            return;
9596        }
9597
9598        enforceNotIsolatedCaller("publishContentProviders");
9599        synchronized (this) {
9600            final ProcessRecord r = getRecordForAppLocked(caller);
9601            if (DEBUG_MU)
9602                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9603            if (r == null) {
9604                throw new SecurityException(
9605                        "Unable to find app for caller " + caller
9606                      + " (pid=" + Binder.getCallingPid()
9607                      + ") when publishing content providers");
9608            }
9609
9610            final long origId = Binder.clearCallingIdentity();
9611
9612            final int N = providers.size();
9613            for (int i=0; i<N; i++) {
9614                ContentProviderHolder src = providers.get(i);
9615                if (src == null || src.info == null || src.provider == null) {
9616                    continue;
9617                }
9618                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9619                if (DEBUG_MU)
9620                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9621                if (dst != null) {
9622                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9623                    mProviderMap.putProviderByClass(comp, dst);
9624                    String names[] = dst.info.authority.split(";");
9625                    for (int j = 0; j < names.length; j++) {
9626                        mProviderMap.putProviderByName(names[j], dst);
9627                    }
9628
9629                    int NL = mLaunchingProviders.size();
9630                    int j;
9631                    for (j=0; j<NL; j++) {
9632                        if (mLaunchingProviders.get(j) == dst) {
9633                            mLaunchingProviders.remove(j);
9634                            j--;
9635                            NL--;
9636                        }
9637                    }
9638                    synchronized (dst) {
9639                        dst.provider = src.provider;
9640                        dst.proc = r;
9641                        dst.notifyAll();
9642                    }
9643                    updateOomAdjLocked(r);
9644                }
9645            }
9646
9647            Binder.restoreCallingIdentity(origId);
9648        }
9649    }
9650
9651    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9652        ContentProviderConnection conn;
9653        try {
9654            conn = (ContentProviderConnection)connection;
9655        } catch (ClassCastException e) {
9656            String msg ="refContentProvider: " + connection
9657                    + " not a ContentProviderConnection";
9658            Slog.w(TAG, msg);
9659            throw new IllegalArgumentException(msg);
9660        }
9661        if (conn == null) {
9662            throw new NullPointerException("connection is null");
9663        }
9664
9665        synchronized (this) {
9666            if (stable > 0) {
9667                conn.numStableIncs += stable;
9668            }
9669            stable = conn.stableCount + stable;
9670            if (stable < 0) {
9671                throw new IllegalStateException("stableCount < 0: " + stable);
9672            }
9673
9674            if (unstable > 0) {
9675                conn.numUnstableIncs += unstable;
9676            }
9677            unstable = conn.unstableCount + unstable;
9678            if (unstable < 0) {
9679                throw new IllegalStateException("unstableCount < 0: " + unstable);
9680            }
9681
9682            if ((stable+unstable) <= 0) {
9683                throw new IllegalStateException("ref counts can't go to zero here: stable="
9684                        + stable + " unstable=" + unstable);
9685            }
9686            conn.stableCount = stable;
9687            conn.unstableCount = unstable;
9688            return !conn.dead;
9689        }
9690    }
9691
9692    public void unstableProviderDied(IBinder connection) {
9693        ContentProviderConnection conn;
9694        try {
9695            conn = (ContentProviderConnection)connection;
9696        } catch (ClassCastException e) {
9697            String msg ="refContentProvider: " + connection
9698                    + " not a ContentProviderConnection";
9699            Slog.w(TAG, msg);
9700            throw new IllegalArgumentException(msg);
9701        }
9702        if (conn == null) {
9703            throw new NullPointerException("connection is null");
9704        }
9705
9706        // Safely retrieve the content provider associated with the connection.
9707        IContentProvider provider;
9708        synchronized (this) {
9709            provider = conn.provider.provider;
9710        }
9711
9712        if (provider == null) {
9713            // Um, yeah, we're way ahead of you.
9714            return;
9715        }
9716
9717        // Make sure the caller is being honest with us.
9718        if (provider.asBinder().pingBinder()) {
9719            // Er, no, still looks good to us.
9720            synchronized (this) {
9721                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9722                        + " says " + conn + " died, but we don't agree");
9723                return;
9724            }
9725        }
9726
9727        // Well look at that!  It's dead!
9728        synchronized (this) {
9729            if (conn.provider.provider != provider) {
9730                // But something changed...  good enough.
9731                return;
9732            }
9733
9734            ProcessRecord proc = conn.provider.proc;
9735            if (proc == null || proc.thread == null) {
9736                // Seems like the process is already cleaned up.
9737                return;
9738            }
9739
9740            // As far as we're concerned, this is just like receiving a
9741            // death notification...  just a bit prematurely.
9742            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9743                    + ") early provider death");
9744            final long ident = Binder.clearCallingIdentity();
9745            try {
9746                appDiedLocked(proc);
9747            } finally {
9748                Binder.restoreCallingIdentity(ident);
9749            }
9750        }
9751    }
9752
9753    @Override
9754    public void appNotRespondingViaProvider(IBinder connection) {
9755        enforceCallingPermission(
9756                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9757
9758        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9759        if (conn == null) {
9760            Slog.w(TAG, "ContentProviderConnection is null");
9761            return;
9762        }
9763
9764        final ProcessRecord host = conn.provider.proc;
9765        if (host == null) {
9766            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9767            return;
9768        }
9769
9770        final long token = Binder.clearCallingIdentity();
9771        try {
9772            appNotResponding(host, null, null, false, "ContentProvider not responding");
9773        } finally {
9774            Binder.restoreCallingIdentity(token);
9775        }
9776    }
9777
9778    public final void installSystemProviders() {
9779        List<ProviderInfo> providers;
9780        synchronized (this) {
9781            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9782            providers = generateApplicationProvidersLocked(app);
9783            if (providers != null) {
9784                for (int i=providers.size()-1; i>=0; i--) {
9785                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9786                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9787                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9788                                + ": not system .apk");
9789                        providers.remove(i);
9790                    }
9791                }
9792            }
9793        }
9794        if (providers != null) {
9795            mSystemThread.installSystemProviders(providers);
9796        }
9797
9798        mCoreSettingsObserver = new CoreSettingsObserver(this);
9799
9800        //mUsageStatsService.monitorPackages();
9801    }
9802
9803    /**
9804     * Allows apps to retrieve the MIME type of a URI.
9805     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9806     * users, then it does not need permission to access the ContentProvider.
9807     * Either, it needs cross-user uri grants.
9808     *
9809     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9810     *
9811     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9812     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9813     */
9814    public String getProviderMimeType(Uri uri, int userId) {
9815        enforceNotIsolatedCaller("getProviderMimeType");
9816        final String name = uri.getAuthority();
9817        int callingUid = Binder.getCallingUid();
9818        int callingPid = Binder.getCallingPid();
9819        long ident = 0;
9820        boolean clearedIdentity = false;
9821        userId = unsafeConvertIncomingUser(userId);
9822        if (canClearIdentity(callingPid, callingUid, userId)) {
9823            clearedIdentity = true;
9824            ident = Binder.clearCallingIdentity();
9825        }
9826        ContentProviderHolder holder = null;
9827        try {
9828            holder = getContentProviderExternalUnchecked(name, null, userId);
9829            if (holder != null) {
9830                return holder.provider.getType(uri);
9831            }
9832        } catch (RemoteException e) {
9833            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9834            return null;
9835        } finally {
9836            // We need to clear the identity to call removeContentProviderExternalUnchecked
9837            if (!clearedIdentity) {
9838                ident = Binder.clearCallingIdentity();
9839            }
9840            try {
9841                if (holder != null) {
9842                    removeContentProviderExternalUnchecked(name, null, userId);
9843                }
9844            } finally {
9845                Binder.restoreCallingIdentity(ident);
9846            }
9847        }
9848
9849        return null;
9850    }
9851
9852    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9853        if (UserHandle.getUserId(callingUid) == userId) {
9854            return true;
9855        }
9856        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9857                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9858                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9859                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9860                return true;
9861        }
9862        return false;
9863    }
9864
9865    // =========================================================
9866    // GLOBAL MANAGEMENT
9867    // =========================================================
9868
9869    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9870            boolean isolated, int isolatedUid) {
9871        String proc = customProcess != null ? customProcess : info.processName;
9872        BatteryStatsImpl.Uid.Proc ps = null;
9873        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9874        int uid = info.uid;
9875        if (isolated) {
9876            if (isolatedUid == 0) {
9877                int userId = UserHandle.getUserId(uid);
9878                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9879                while (true) {
9880                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9881                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9882                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9883                    }
9884                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9885                    mNextIsolatedProcessUid++;
9886                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9887                        // No process for this uid, use it.
9888                        break;
9889                    }
9890                    stepsLeft--;
9891                    if (stepsLeft <= 0) {
9892                        return null;
9893                    }
9894                }
9895            } else {
9896                // Special case for startIsolatedProcess (internal only), where
9897                // the uid of the isolated process is specified by the caller.
9898                uid = isolatedUid;
9899            }
9900        }
9901        return new ProcessRecord(stats, info, proc, uid);
9902    }
9903
9904    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9905            String abiOverride) {
9906        ProcessRecord app;
9907        if (!isolated) {
9908            app = getProcessRecordLocked(info.processName, info.uid, true);
9909        } else {
9910            app = null;
9911        }
9912
9913        if (app == null) {
9914            app = newProcessRecordLocked(info, null, isolated, 0);
9915            mProcessNames.put(info.processName, app.uid, app);
9916            if (isolated) {
9917                mIsolatedProcesses.put(app.uid, app);
9918            }
9919            updateLruProcessLocked(app, false, null);
9920            updateOomAdjLocked();
9921        }
9922
9923        // This package really, really can not be stopped.
9924        try {
9925            AppGlobals.getPackageManager().setPackageStoppedState(
9926                    info.packageName, false, UserHandle.getUserId(app.uid));
9927        } catch (RemoteException e) {
9928        } catch (IllegalArgumentException e) {
9929            Slog.w(TAG, "Failed trying to unstop package "
9930                    + info.packageName + ": " + e);
9931        }
9932
9933        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9934                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9935            app.persistent = true;
9936            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9937        }
9938        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9939            mPersistentStartingProcesses.add(app);
9940            startProcessLocked(app, "added application", app.processName, abiOverride,
9941                    null /* entryPoint */, null /* entryPointArgs */);
9942        }
9943
9944        return app;
9945    }
9946
9947    public void unhandledBack() {
9948        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9949                "unhandledBack()");
9950
9951        synchronized(this) {
9952            final long origId = Binder.clearCallingIdentity();
9953            try {
9954                getFocusedStack().unhandledBackLocked();
9955            } finally {
9956                Binder.restoreCallingIdentity(origId);
9957            }
9958        }
9959    }
9960
9961    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9962        enforceNotIsolatedCaller("openContentUri");
9963        final int userId = UserHandle.getCallingUserId();
9964        String name = uri.getAuthority();
9965        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9966        ParcelFileDescriptor pfd = null;
9967        if (cph != null) {
9968            // We record the binder invoker's uid in thread-local storage before
9969            // going to the content provider to open the file.  Later, in the code
9970            // that handles all permissions checks, we look for this uid and use
9971            // that rather than the Activity Manager's own uid.  The effect is that
9972            // we do the check against the caller's permissions even though it looks
9973            // to the content provider like the Activity Manager itself is making
9974            // the request.
9975            Binder token = new Binder();
9976            sCallerIdentity.set(new Identity(
9977                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9978            try {
9979                pfd = cph.provider.openFile(null, uri, "r", null, token);
9980            } catch (FileNotFoundException e) {
9981                // do nothing; pfd will be returned null
9982            } finally {
9983                // Ensure that whatever happens, we clean up the identity state
9984                sCallerIdentity.remove();
9985            }
9986
9987            // We've got the fd now, so we're done with the provider.
9988            removeContentProviderExternalUnchecked(name, null, userId);
9989        } else {
9990            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9991        }
9992        return pfd;
9993    }
9994
9995    // Actually is sleeping or shutting down or whatever else in the future
9996    // is an inactive state.
9997    public boolean isSleepingOrShuttingDown() {
9998        return isSleeping() || mShuttingDown;
9999    }
10000
10001    public boolean isSleeping() {
10002        return mSleeping;
10003    }
10004
10005    void onWakefulnessChanged(int wakefulness) {
10006        synchronized(this) {
10007            mWakefulness = wakefulness;
10008            updateSleepIfNeededLocked();
10009        }
10010    }
10011
10012    void finishRunningVoiceLocked() {
10013        if (mRunningVoice) {
10014            mRunningVoice = false;
10015            updateSleepIfNeededLocked();
10016        }
10017    }
10018
10019    void updateSleepIfNeededLocked() {
10020        if (mSleeping && !shouldSleepLocked()) {
10021            mSleeping = false;
10022            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10023        } else if (!mSleeping && shouldSleepLocked()) {
10024            mSleeping = true;
10025            mStackSupervisor.goingToSleepLocked();
10026
10027            // Initialize the wake times of all processes.
10028            checkExcessivePowerUsageLocked(false);
10029            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10030            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10031            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10032        }
10033    }
10034
10035    private boolean shouldSleepLocked() {
10036        // Resume applications while running a voice interactor.
10037        if (mRunningVoice) {
10038            return false;
10039        }
10040
10041        switch (mWakefulness) {
10042            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10043            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10044                // If we're interactive but applications are already paused then defer
10045                // resuming them until the lock screen is hidden.
10046                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10047            case PowerManagerInternal.WAKEFULNESS_DOZING:
10048                // If we're dozing then pause applications whenever the lock screen is shown.
10049                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10050            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10051            default:
10052                // If we're asleep then pause applications unconditionally.
10053                return true;
10054        }
10055    }
10056
10057    /** Pokes the task persister. */
10058    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10059        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10060            // Never persist the home stack.
10061            return;
10062        }
10063        mTaskPersister.wakeup(task, flush);
10064    }
10065
10066    /** Notifies all listeners when the task stack has changed. */
10067    void notifyTaskStackChangedLocked() {
10068        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10069        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10070        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10071    }
10072
10073    @Override
10074    public boolean shutdown(int timeout) {
10075        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10076                != PackageManager.PERMISSION_GRANTED) {
10077            throw new SecurityException("Requires permission "
10078                    + android.Manifest.permission.SHUTDOWN);
10079        }
10080
10081        boolean timedout = false;
10082
10083        synchronized(this) {
10084            mShuttingDown = true;
10085            updateEventDispatchingLocked();
10086            timedout = mStackSupervisor.shutdownLocked(timeout);
10087        }
10088
10089        mAppOpsService.shutdown();
10090        if (mUsageStatsService != null) {
10091            mUsageStatsService.prepareShutdown();
10092        }
10093        mBatteryStatsService.shutdown();
10094        synchronized (this) {
10095            mProcessStats.shutdownLocked();
10096            notifyTaskPersisterLocked(null, true);
10097        }
10098
10099        return timedout;
10100    }
10101
10102    public final void activitySlept(IBinder token) {
10103        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10104
10105        final long origId = Binder.clearCallingIdentity();
10106
10107        synchronized (this) {
10108            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10109            if (r != null) {
10110                mStackSupervisor.activitySleptLocked(r);
10111            }
10112        }
10113
10114        Binder.restoreCallingIdentity(origId);
10115    }
10116
10117    private String lockScreenShownToString() {
10118        switch (mLockScreenShown) {
10119            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10120            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10121            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10122            default: return "Unknown=" + mLockScreenShown;
10123        }
10124    }
10125
10126    void logLockScreen(String msg) {
10127        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10128                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10129                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10130                + " mSleeping=" + mSleeping);
10131    }
10132
10133    void startRunningVoiceLocked() {
10134        if (!mRunningVoice) {
10135            mRunningVoice = true;
10136            updateSleepIfNeededLocked();
10137        }
10138    }
10139
10140    private void updateEventDispatchingLocked() {
10141        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10142    }
10143
10144    public void setLockScreenShown(boolean shown) {
10145        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10146                != PackageManager.PERMISSION_GRANTED) {
10147            throw new SecurityException("Requires permission "
10148                    + android.Manifest.permission.DEVICE_POWER);
10149        }
10150
10151        synchronized(this) {
10152            long ident = Binder.clearCallingIdentity();
10153            try {
10154                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10155                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10156                updateSleepIfNeededLocked();
10157            } finally {
10158                Binder.restoreCallingIdentity(ident);
10159            }
10160        }
10161    }
10162
10163    @Override
10164    public void stopAppSwitches() {
10165        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10166                != PackageManager.PERMISSION_GRANTED) {
10167            throw new SecurityException("Requires permission "
10168                    + android.Manifest.permission.STOP_APP_SWITCHES);
10169        }
10170
10171        synchronized(this) {
10172            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10173                    + APP_SWITCH_DELAY_TIME;
10174            mDidAppSwitch = false;
10175            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10176            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10177            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10178        }
10179    }
10180
10181    public void resumeAppSwitches() {
10182        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10183                != PackageManager.PERMISSION_GRANTED) {
10184            throw new SecurityException("Requires permission "
10185                    + android.Manifest.permission.STOP_APP_SWITCHES);
10186        }
10187
10188        synchronized(this) {
10189            // Note that we don't execute any pending app switches... we will
10190            // let those wait until either the timeout, or the next start
10191            // activity request.
10192            mAppSwitchesAllowedTime = 0;
10193        }
10194    }
10195
10196    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10197            int callingPid, int callingUid, String name) {
10198        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10199            return true;
10200        }
10201
10202        int perm = checkComponentPermission(
10203                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10204                sourceUid, -1, true);
10205        if (perm == PackageManager.PERMISSION_GRANTED) {
10206            return true;
10207        }
10208
10209        // If the actual IPC caller is different from the logical source, then
10210        // also see if they are allowed to control app switches.
10211        if (callingUid != -1 && callingUid != sourceUid) {
10212            perm = checkComponentPermission(
10213                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10214                    callingUid, -1, true);
10215            if (perm == PackageManager.PERMISSION_GRANTED) {
10216                return true;
10217            }
10218        }
10219
10220        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10221        return false;
10222    }
10223
10224    public void setDebugApp(String packageName, boolean waitForDebugger,
10225            boolean persistent) {
10226        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10227                "setDebugApp()");
10228
10229        long ident = Binder.clearCallingIdentity();
10230        try {
10231            // Note that this is not really thread safe if there are multiple
10232            // callers into it at the same time, but that's not a situation we
10233            // care about.
10234            if (persistent) {
10235                final ContentResolver resolver = mContext.getContentResolver();
10236                Settings.Global.putString(
10237                    resolver, Settings.Global.DEBUG_APP,
10238                    packageName);
10239                Settings.Global.putInt(
10240                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10241                    waitForDebugger ? 1 : 0);
10242            }
10243
10244            synchronized (this) {
10245                if (!persistent) {
10246                    mOrigDebugApp = mDebugApp;
10247                    mOrigWaitForDebugger = mWaitForDebugger;
10248                }
10249                mDebugApp = packageName;
10250                mWaitForDebugger = waitForDebugger;
10251                mDebugTransient = !persistent;
10252                if (packageName != null) {
10253                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10254                            false, UserHandle.USER_ALL, "set debug app");
10255                }
10256            }
10257        } finally {
10258            Binder.restoreCallingIdentity(ident);
10259        }
10260    }
10261
10262    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10263        synchronized (this) {
10264            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10265            if (!isDebuggable) {
10266                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10267                    throw new SecurityException("Process not debuggable: " + app.packageName);
10268                }
10269            }
10270
10271            mOpenGlTraceApp = processName;
10272        }
10273    }
10274
10275    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10276        synchronized (this) {
10277            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10278            if (!isDebuggable) {
10279                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10280                    throw new SecurityException("Process not debuggable: " + app.packageName);
10281                }
10282            }
10283            mProfileApp = processName;
10284            mProfileFile = profilerInfo.profileFile;
10285            if (mProfileFd != null) {
10286                try {
10287                    mProfileFd.close();
10288                } catch (IOException e) {
10289                }
10290                mProfileFd = null;
10291            }
10292            mProfileFd = profilerInfo.profileFd;
10293            mSamplingInterval = profilerInfo.samplingInterval;
10294            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10295            mProfileType = 0;
10296        }
10297    }
10298
10299    @Override
10300    public void setAlwaysFinish(boolean enabled) {
10301        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10302                "setAlwaysFinish()");
10303
10304        Settings.Global.putInt(
10305                mContext.getContentResolver(),
10306                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10307
10308        synchronized (this) {
10309            mAlwaysFinishActivities = enabled;
10310        }
10311    }
10312
10313    @Override
10314    public void setActivityController(IActivityController controller) {
10315        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10316                "setActivityController()");
10317        synchronized (this) {
10318            mController = controller;
10319            Watchdog.getInstance().setActivityController(controller);
10320        }
10321    }
10322
10323    @Override
10324    public void setUserIsMonkey(boolean userIsMonkey) {
10325        synchronized (this) {
10326            synchronized (mPidsSelfLocked) {
10327                final int callingPid = Binder.getCallingPid();
10328                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10329                if (precessRecord == null) {
10330                    throw new SecurityException("Unknown process: " + callingPid);
10331                }
10332                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10333                    throw new SecurityException("Only an instrumentation process "
10334                            + "with a UiAutomation can call setUserIsMonkey");
10335                }
10336            }
10337            mUserIsMonkey = userIsMonkey;
10338        }
10339    }
10340
10341    @Override
10342    public boolean isUserAMonkey() {
10343        synchronized (this) {
10344            // If there is a controller also implies the user is a monkey.
10345            return (mUserIsMonkey || mController != null);
10346        }
10347    }
10348
10349    public void requestBugReport() {
10350        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10351        SystemProperties.set("ctl.start", "bugreport");
10352    }
10353
10354    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10355        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10356    }
10357
10358    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10359        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10360            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10361        }
10362        return KEY_DISPATCHING_TIMEOUT;
10363    }
10364
10365    @Override
10366    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10367        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10368                != PackageManager.PERMISSION_GRANTED) {
10369            throw new SecurityException("Requires permission "
10370                    + android.Manifest.permission.FILTER_EVENTS);
10371        }
10372        ProcessRecord proc;
10373        long timeout;
10374        synchronized (this) {
10375            synchronized (mPidsSelfLocked) {
10376                proc = mPidsSelfLocked.get(pid);
10377            }
10378            timeout = getInputDispatchingTimeoutLocked(proc);
10379        }
10380
10381        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10382            return -1;
10383        }
10384
10385        return timeout;
10386    }
10387
10388    /**
10389     * Handle input dispatching timeouts.
10390     * Returns whether input dispatching should be aborted or not.
10391     */
10392    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10393            final ActivityRecord activity, final ActivityRecord parent,
10394            final boolean aboveSystem, String reason) {
10395        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10396                != PackageManager.PERMISSION_GRANTED) {
10397            throw new SecurityException("Requires permission "
10398                    + android.Manifest.permission.FILTER_EVENTS);
10399        }
10400
10401        final String annotation;
10402        if (reason == null) {
10403            annotation = "Input dispatching timed out";
10404        } else {
10405            annotation = "Input dispatching timed out (" + reason + ")";
10406        }
10407
10408        if (proc != null) {
10409            synchronized (this) {
10410                if (proc.debugging) {
10411                    return false;
10412                }
10413
10414                if (mDidDexOpt) {
10415                    // Give more time since we were dexopting.
10416                    mDidDexOpt = false;
10417                    return false;
10418                }
10419
10420                if (proc.instrumentationClass != null) {
10421                    Bundle info = new Bundle();
10422                    info.putString("shortMsg", "keyDispatchingTimedOut");
10423                    info.putString("longMsg", annotation);
10424                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10425                    return true;
10426                }
10427            }
10428            mHandler.post(new Runnable() {
10429                @Override
10430                public void run() {
10431                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10432                }
10433            });
10434        }
10435
10436        return true;
10437    }
10438
10439    public Bundle getAssistContextExtras(int requestType) {
10440        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10441                UserHandle.getCallingUserId());
10442        if (pae == null) {
10443            return null;
10444        }
10445        synchronized (pae) {
10446            while (!pae.haveResult) {
10447                try {
10448                    pae.wait();
10449                } catch (InterruptedException e) {
10450                }
10451            }
10452            if (pae.result != null) {
10453                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10454            }
10455        }
10456        synchronized (this) {
10457            mPendingAssistExtras.remove(pae);
10458            mHandler.removeCallbacks(pae);
10459        }
10460        return pae.extras;
10461    }
10462
10463    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10464            int userHandle) {
10465        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10466                "getAssistContextExtras()");
10467        PendingAssistExtras pae;
10468        Bundle extras = new Bundle();
10469        synchronized (this) {
10470            ActivityRecord activity = getFocusedStack().mResumedActivity;
10471            if (activity == null) {
10472                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10473                return null;
10474            }
10475            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10476            if (activity.app == null || activity.app.thread == null) {
10477                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10478                return null;
10479            }
10480            if (activity.app.pid == Binder.getCallingPid()) {
10481                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10482                return null;
10483            }
10484            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10485            try {
10486                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10487                        requestType);
10488                mPendingAssistExtras.add(pae);
10489                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10490            } catch (RemoteException e) {
10491                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10492                return null;
10493            }
10494            return pae;
10495        }
10496    }
10497
10498    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10499        PendingAssistExtras pae = (PendingAssistExtras)token;
10500        synchronized (pae) {
10501            pae.result = extras;
10502            pae.haveResult = true;
10503            pae.notifyAll();
10504            if (pae.intent == null) {
10505                // Caller is just waiting for the result.
10506                return;
10507            }
10508        }
10509
10510        // We are now ready to launch the assist activity.
10511        synchronized (this) {
10512            boolean exists = mPendingAssistExtras.remove(pae);
10513            mHandler.removeCallbacks(pae);
10514            if (!exists) {
10515                // Timed out.
10516                return;
10517            }
10518        }
10519        pae.intent.replaceExtras(extras);
10520        if (pae.hint != null) {
10521            pae.intent.putExtra(pae.hint, true);
10522        }
10523        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10524                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10525                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10526        closeSystemDialogs("assist");
10527        try {
10528            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10529        } catch (ActivityNotFoundException e) {
10530            Slog.w(TAG, "No activity to handle assist action.", e);
10531        }
10532    }
10533
10534    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10535        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10536    }
10537
10538    public void registerProcessObserver(IProcessObserver observer) {
10539        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10540                "registerProcessObserver()");
10541        synchronized (this) {
10542            mProcessObservers.register(observer);
10543        }
10544    }
10545
10546    @Override
10547    public void unregisterProcessObserver(IProcessObserver observer) {
10548        synchronized (this) {
10549            mProcessObservers.unregister(observer);
10550        }
10551    }
10552
10553    @Override
10554    public boolean convertFromTranslucent(IBinder token) {
10555        final long origId = Binder.clearCallingIdentity();
10556        try {
10557            synchronized (this) {
10558                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10559                if (r == null) {
10560                    return false;
10561                }
10562                final boolean translucentChanged = r.changeWindowTranslucency(true);
10563                if (translucentChanged) {
10564                    r.task.stack.releaseBackgroundResources();
10565                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10566                }
10567                mWindowManager.setAppFullscreen(token, true);
10568                return translucentChanged;
10569            }
10570        } finally {
10571            Binder.restoreCallingIdentity(origId);
10572        }
10573    }
10574
10575    @Override
10576    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10577        final long origId = Binder.clearCallingIdentity();
10578        try {
10579            synchronized (this) {
10580                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10581                if (r == null) {
10582                    return false;
10583                }
10584                int index = r.task.mActivities.lastIndexOf(r);
10585                if (index > 0) {
10586                    ActivityRecord under = r.task.mActivities.get(index - 1);
10587                    under.returningOptions = options;
10588                }
10589                final boolean translucentChanged = r.changeWindowTranslucency(false);
10590                if (translucentChanged) {
10591                    r.task.stack.convertToTranslucent(r);
10592                }
10593                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10594                mWindowManager.setAppFullscreen(token, false);
10595                return translucentChanged;
10596            }
10597        } finally {
10598            Binder.restoreCallingIdentity(origId);
10599        }
10600    }
10601
10602    @Override
10603    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10604        final long origId = Binder.clearCallingIdentity();
10605        try {
10606            synchronized (this) {
10607                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10608                if (r != null) {
10609                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10610                }
10611            }
10612            return false;
10613        } finally {
10614            Binder.restoreCallingIdentity(origId);
10615        }
10616    }
10617
10618    @Override
10619    public boolean isBackgroundVisibleBehind(IBinder token) {
10620        final long origId = Binder.clearCallingIdentity();
10621        try {
10622            synchronized (this) {
10623                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10624                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10625                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10626                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10627                return visible;
10628            }
10629        } finally {
10630            Binder.restoreCallingIdentity(origId);
10631        }
10632    }
10633
10634    @Override
10635    public ActivityOptions getActivityOptions(IBinder token) {
10636        final long origId = Binder.clearCallingIdentity();
10637        try {
10638            synchronized (this) {
10639                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10640                if (r != null) {
10641                    final ActivityOptions activityOptions = r.pendingOptions;
10642                    r.pendingOptions = null;
10643                    return activityOptions;
10644                }
10645                return null;
10646            }
10647        } finally {
10648            Binder.restoreCallingIdentity(origId);
10649        }
10650    }
10651
10652    @Override
10653    public void setImmersive(IBinder token, boolean immersive) {
10654        synchronized(this) {
10655            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10656            if (r == null) {
10657                throw new IllegalArgumentException();
10658            }
10659            r.immersive = immersive;
10660
10661            // update associated state if we're frontmost
10662            if (r == mFocusedActivity) {
10663                if (DEBUG_IMMERSIVE) {
10664                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10665                }
10666                applyUpdateLockStateLocked(r);
10667            }
10668        }
10669    }
10670
10671    @Override
10672    public boolean isImmersive(IBinder token) {
10673        synchronized (this) {
10674            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10675            if (r == null) {
10676                throw new IllegalArgumentException();
10677            }
10678            return r.immersive;
10679        }
10680    }
10681
10682    public boolean isTopActivityImmersive() {
10683        enforceNotIsolatedCaller("startActivity");
10684        synchronized (this) {
10685            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10686            return (r != null) ? r.immersive : false;
10687        }
10688    }
10689
10690    @Override
10691    public boolean isTopOfTask(IBinder token) {
10692        synchronized (this) {
10693            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10694            if (r == null) {
10695                throw new IllegalArgumentException();
10696            }
10697            return r.task.getTopActivity() == r;
10698        }
10699    }
10700
10701    public final void enterSafeMode() {
10702        synchronized(this) {
10703            // It only makes sense to do this before the system is ready
10704            // and started launching other packages.
10705            if (!mSystemReady) {
10706                try {
10707                    AppGlobals.getPackageManager().enterSafeMode();
10708                } catch (RemoteException e) {
10709                }
10710            }
10711
10712            mSafeMode = true;
10713        }
10714    }
10715
10716    public final void showSafeModeOverlay() {
10717        View v = LayoutInflater.from(mContext).inflate(
10718                com.android.internal.R.layout.safe_mode, null);
10719        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10720        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10721        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10722        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10723        lp.gravity = Gravity.BOTTOM | Gravity.START;
10724        lp.format = v.getBackground().getOpacity();
10725        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10726                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10727        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10728        ((WindowManager)mContext.getSystemService(
10729                Context.WINDOW_SERVICE)).addView(v, lp);
10730    }
10731
10732    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10733        if (!(sender instanceof PendingIntentRecord)) {
10734            return;
10735        }
10736        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10737        synchronized (stats) {
10738            if (mBatteryStatsService.isOnBattery()) {
10739                mBatteryStatsService.enforceCallingPermission();
10740                PendingIntentRecord rec = (PendingIntentRecord)sender;
10741                int MY_UID = Binder.getCallingUid();
10742                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10743                BatteryStatsImpl.Uid.Pkg pkg =
10744                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10745                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10746                pkg.incWakeupsLocked();
10747            }
10748        }
10749    }
10750
10751    public boolean killPids(int[] pids, String pReason, boolean secure) {
10752        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10753            throw new SecurityException("killPids only available to the system");
10754        }
10755        String reason = (pReason == null) ? "Unknown" : pReason;
10756        // XXX Note: don't acquire main activity lock here, because the window
10757        // manager calls in with its locks held.
10758
10759        boolean killed = false;
10760        synchronized (mPidsSelfLocked) {
10761            int[] types = new int[pids.length];
10762            int worstType = 0;
10763            for (int i=0; i<pids.length; i++) {
10764                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10765                if (proc != null) {
10766                    int type = proc.setAdj;
10767                    types[i] = type;
10768                    if (type > worstType) {
10769                        worstType = type;
10770                    }
10771                }
10772            }
10773
10774            // If the worst oom_adj is somewhere in the cached proc LRU range,
10775            // then constrain it so we will kill all cached procs.
10776            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10777                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10778                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10779            }
10780
10781            // If this is not a secure call, don't let it kill processes that
10782            // are important.
10783            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10784                worstType = ProcessList.SERVICE_ADJ;
10785            }
10786
10787            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10788            for (int i=0; i<pids.length; i++) {
10789                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10790                if (proc == null) {
10791                    continue;
10792                }
10793                int adj = proc.setAdj;
10794                if (adj >= worstType && !proc.killedByAm) {
10795                    proc.kill(reason, true);
10796                    killed = true;
10797                }
10798            }
10799        }
10800        return killed;
10801    }
10802
10803    @Override
10804    public void killUid(int uid, String reason) {
10805        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10806            throw new SecurityException("killUid only available to the system");
10807        }
10808        synchronized (this) {
10809            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10810                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10811                    reason != null ? reason : "kill uid");
10812        }
10813    }
10814
10815    @Override
10816    public boolean killProcessesBelowForeground(String reason) {
10817        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10818            throw new SecurityException("killProcessesBelowForeground() only available to system");
10819        }
10820
10821        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10822    }
10823
10824    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10825        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10826            throw new SecurityException("killProcessesBelowAdj() only available to system");
10827        }
10828
10829        boolean killed = false;
10830        synchronized (mPidsSelfLocked) {
10831            final int size = mPidsSelfLocked.size();
10832            for (int i = 0; i < size; i++) {
10833                final int pid = mPidsSelfLocked.keyAt(i);
10834                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10835                if (proc == null) continue;
10836
10837                final int adj = proc.setAdj;
10838                if (adj > belowAdj && !proc.killedByAm) {
10839                    proc.kill(reason, true);
10840                    killed = true;
10841                }
10842            }
10843        }
10844        return killed;
10845    }
10846
10847    @Override
10848    public void hang(final IBinder who, boolean allowRestart) {
10849        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10850                != PackageManager.PERMISSION_GRANTED) {
10851            throw new SecurityException("Requires permission "
10852                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10853        }
10854
10855        final IBinder.DeathRecipient death = new DeathRecipient() {
10856            @Override
10857            public void binderDied() {
10858                synchronized (this) {
10859                    notifyAll();
10860                }
10861            }
10862        };
10863
10864        try {
10865            who.linkToDeath(death, 0);
10866        } catch (RemoteException e) {
10867            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10868            return;
10869        }
10870
10871        synchronized (this) {
10872            Watchdog.getInstance().setAllowRestart(allowRestart);
10873            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10874            synchronized (death) {
10875                while (who.isBinderAlive()) {
10876                    try {
10877                        death.wait();
10878                    } catch (InterruptedException e) {
10879                    }
10880                }
10881            }
10882            Watchdog.getInstance().setAllowRestart(true);
10883        }
10884    }
10885
10886    @Override
10887    public void restart() {
10888        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10889                != PackageManager.PERMISSION_GRANTED) {
10890            throw new SecurityException("Requires permission "
10891                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10892        }
10893
10894        Log.i(TAG, "Sending shutdown broadcast...");
10895
10896        BroadcastReceiver br = new BroadcastReceiver() {
10897            @Override public void onReceive(Context context, Intent intent) {
10898                // Now the broadcast is done, finish up the low-level shutdown.
10899                Log.i(TAG, "Shutting down activity manager...");
10900                shutdown(10000);
10901                Log.i(TAG, "Shutdown complete, restarting!");
10902                Process.killProcess(Process.myPid());
10903                System.exit(10);
10904            }
10905        };
10906
10907        // First send the high-level shut down broadcast.
10908        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10909        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10910        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10911        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10912        mContext.sendOrderedBroadcastAsUser(intent,
10913                UserHandle.ALL, null, br, mHandler, 0, null, null);
10914        */
10915        br.onReceive(mContext, intent);
10916    }
10917
10918    private long getLowRamTimeSinceIdle(long now) {
10919        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10920    }
10921
10922    @Override
10923    public void performIdleMaintenance() {
10924        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10925                != PackageManager.PERMISSION_GRANTED) {
10926            throw new SecurityException("Requires permission "
10927                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10928        }
10929
10930        synchronized (this) {
10931            final long now = SystemClock.uptimeMillis();
10932            final long timeSinceLastIdle = now - mLastIdleTime;
10933            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10934            mLastIdleTime = now;
10935            mLowRamTimeSinceLastIdle = 0;
10936            if (mLowRamStartTime != 0) {
10937                mLowRamStartTime = now;
10938            }
10939
10940            StringBuilder sb = new StringBuilder(128);
10941            sb.append("Idle maintenance over ");
10942            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10943            sb.append(" low RAM for ");
10944            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10945            Slog.i(TAG, sb.toString());
10946
10947            // If at least 1/3 of our time since the last idle period has been spent
10948            // with RAM low, then we want to kill processes.
10949            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10950
10951            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10952                ProcessRecord proc = mLruProcesses.get(i);
10953                if (proc.notCachedSinceIdle) {
10954                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10955                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10956                        if (doKilling && proc.initialIdlePss != 0
10957                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10958                            sb = new StringBuilder(128);
10959                            sb.append("Kill");
10960                            sb.append(proc.processName);
10961                            sb.append(" in idle maint: pss=");
10962                            sb.append(proc.lastPss);
10963                            sb.append(", initialPss=");
10964                            sb.append(proc.initialIdlePss);
10965                            sb.append(", period=");
10966                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10967                            sb.append(", lowRamPeriod=");
10968                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10969                            Slog.wtfQuiet(TAG, sb.toString());
10970                            proc.kill("idle maint (pss " + proc.lastPss
10971                                    + " from " + proc.initialIdlePss + ")", true);
10972                        }
10973                    }
10974                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10975                    proc.notCachedSinceIdle = true;
10976                    proc.initialIdlePss = 0;
10977                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10978                            mTestPssMode, isSleeping(), now);
10979                }
10980            }
10981
10982            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10983            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10984        }
10985    }
10986
10987    private void retrieveSettings() {
10988        final ContentResolver resolver = mContext.getContentResolver();
10989        String debugApp = Settings.Global.getString(
10990            resolver, Settings.Global.DEBUG_APP);
10991        boolean waitForDebugger = Settings.Global.getInt(
10992            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10993        boolean alwaysFinishActivities = Settings.Global.getInt(
10994            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10995        boolean forceRtl = Settings.Global.getInt(
10996                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10997        // Transfer any global setting for forcing RTL layout, into a System Property
10998        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10999
11000        Configuration configuration = new Configuration();
11001        Settings.System.getConfiguration(resolver, configuration);
11002        if (forceRtl) {
11003            // This will take care of setting the correct layout direction flags
11004            configuration.setLayoutDirection(configuration.locale);
11005        }
11006
11007        synchronized (this) {
11008            mDebugApp = mOrigDebugApp = debugApp;
11009            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11010            mAlwaysFinishActivities = alwaysFinishActivities;
11011            // This happens before any activities are started, so we can
11012            // change mConfiguration in-place.
11013            updateConfigurationLocked(configuration, null, false, true);
11014            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11015        }
11016    }
11017
11018    /** Loads resources after the current configuration has been set. */
11019    private void loadResourcesOnSystemReady() {
11020        final Resources res = mContext.getResources();
11021        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11022        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11023        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11024    }
11025
11026    public boolean testIsSystemReady() {
11027        // no need to synchronize(this) just to read & return the value
11028        return mSystemReady;
11029    }
11030
11031    private static File getCalledPreBootReceiversFile() {
11032        File dataDir = Environment.getDataDirectory();
11033        File systemDir = new File(dataDir, "system");
11034        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11035        return fname;
11036    }
11037
11038    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11039        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11040        File file = getCalledPreBootReceiversFile();
11041        FileInputStream fis = null;
11042        try {
11043            fis = new FileInputStream(file);
11044            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11045            int fvers = dis.readInt();
11046            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11047                String vers = dis.readUTF();
11048                String codename = dis.readUTF();
11049                String build = dis.readUTF();
11050                if (android.os.Build.VERSION.RELEASE.equals(vers)
11051                        && android.os.Build.VERSION.CODENAME.equals(codename)
11052                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11053                    int num = dis.readInt();
11054                    while (num > 0) {
11055                        num--;
11056                        String pkg = dis.readUTF();
11057                        String cls = dis.readUTF();
11058                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11059                    }
11060                }
11061            }
11062        } catch (FileNotFoundException e) {
11063        } catch (IOException e) {
11064            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11065        } finally {
11066            if (fis != null) {
11067                try {
11068                    fis.close();
11069                } catch (IOException e) {
11070                }
11071            }
11072        }
11073        return lastDoneReceivers;
11074    }
11075
11076    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11077        File file = getCalledPreBootReceiversFile();
11078        FileOutputStream fos = null;
11079        DataOutputStream dos = null;
11080        try {
11081            fos = new FileOutputStream(file);
11082            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11083            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11084            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11085            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11086            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11087            dos.writeInt(list.size());
11088            for (int i=0; i<list.size(); i++) {
11089                dos.writeUTF(list.get(i).getPackageName());
11090                dos.writeUTF(list.get(i).getClassName());
11091            }
11092        } catch (IOException e) {
11093            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11094            file.delete();
11095        } finally {
11096            FileUtils.sync(fos);
11097            if (dos != null) {
11098                try {
11099                    dos.close();
11100                } catch (IOException e) {
11101                    // TODO Auto-generated catch block
11102                    e.printStackTrace();
11103                }
11104            }
11105        }
11106    }
11107
11108    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11109            ArrayList<ComponentName> doneReceivers, int userId) {
11110        boolean waitingUpdate = false;
11111        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11112        List<ResolveInfo> ris = null;
11113        try {
11114            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11115                    intent, null, 0, userId);
11116        } catch (RemoteException e) {
11117        }
11118        if (ris != null) {
11119            for (int i=ris.size()-1; i>=0; i--) {
11120                if ((ris.get(i).activityInfo.applicationInfo.flags
11121                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11122                    ris.remove(i);
11123                }
11124            }
11125            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11126
11127            // For User 0, load the version number. When delivering to a new user, deliver
11128            // to all receivers.
11129            if (userId == UserHandle.USER_OWNER) {
11130                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11131                for (int i=0; i<ris.size(); i++) {
11132                    ActivityInfo ai = ris.get(i).activityInfo;
11133                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11134                    if (lastDoneReceivers.contains(comp)) {
11135                        // We already did the pre boot receiver for this app with the current
11136                        // platform version, so don't do it again...
11137                        ris.remove(i);
11138                        i--;
11139                        // ...however, do keep it as one that has been done, so we don't
11140                        // forget about it when rewriting the file of last done receivers.
11141                        doneReceivers.add(comp);
11142                    }
11143                }
11144            }
11145
11146            // If primary user, send broadcast to all available users, else just to userId
11147            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11148                    : new int[] { userId };
11149            for (int i = 0; i < ris.size(); i++) {
11150                ActivityInfo ai = ris.get(i).activityInfo;
11151                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11152                doneReceivers.add(comp);
11153                intent.setComponent(comp);
11154                for (int j=0; j<users.length; j++) {
11155                    IIntentReceiver finisher = null;
11156                    // On last receiver and user, set up a completion callback
11157                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11158                        finisher = new IIntentReceiver.Stub() {
11159                            public void performReceive(Intent intent, int resultCode,
11160                                    String data, Bundle extras, boolean ordered,
11161                                    boolean sticky, int sendingUser) {
11162                                // The raw IIntentReceiver interface is called
11163                                // with the AM lock held, so redispatch to
11164                                // execute our code without the lock.
11165                                mHandler.post(onFinishCallback);
11166                            }
11167                        };
11168                    }
11169                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11170                            + " for user " + users[j]);
11171                    broadcastIntentLocked(null, null, intent, null, finisher,
11172                            0, null, null, null, AppOpsManager.OP_NONE,
11173                            true, false, MY_PID, Process.SYSTEM_UID,
11174                            users[j]);
11175                    if (finisher != null) {
11176                        waitingUpdate = true;
11177                    }
11178                }
11179            }
11180        }
11181
11182        return waitingUpdate;
11183    }
11184
11185    public void systemReady(final Runnable goingCallback) {
11186        synchronized(this) {
11187            if (mSystemReady) {
11188                // If we're done calling all the receivers, run the next "boot phase" passed in
11189                // by the SystemServer
11190                if (goingCallback != null) {
11191                    goingCallback.run();
11192                }
11193                return;
11194            }
11195
11196            // Make sure we have the current profile info, since it is needed for
11197            // security checks.
11198            updateCurrentProfileIdsLocked();
11199
11200            if (mRecentTasks == null) {
11201                mRecentTasks = mTaskPersister.restoreTasksLocked();
11202                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11203                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11204                mTaskPersister.startPersisting();
11205            }
11206
11207            // Check to see if there are any update receivers to run.
11208            if (!mDidUpdate) {
11209                if (mWaitingUpdate) {
11210                    return;
11211                }
11212                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11213                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11214                    public void run() {
11215                        synchronized (ActivityManagerService.this) {
11216                            mDidUpdate = true;
11217                        }
11218                        writeLastDonePreBootReceivers(doneReceivers);
11219                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11220                                false);
11221                        systemReady(goingCallback);
11222                    }
11223                }, doneReceivers, UserHandle.USER_OWNER);
11224
11225                if (mWaitingUpdate) {
11226                    return;
11227                }
11228                mDidUpdate = true;
11229            }
11230
11231            mAppOpsService.systemReady();
11232            mSystemReady = true;
11233        }
11234
11235        ArrayList<ProcessRecord> procsToKill = null;
11236        synchronized(mPidsSelfLocked) {
11237            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11238                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11239                if (!isAllowedWhileBooting(proc.info)){
11240                    if (procsToKill == null) {
11241                        procsToKill = new ArrayList<ProcessRecord>();
11242                    }
11243                    procsToKill.add(proc);
11244                }
11245            }
11246        }
11247
11248        synchronized(this) {
11249            if (procsToKill != null) {
11250                for (int i=procsToKill.size()-1; i>=0; i--) {
11251                    ProcessRecord proc = procsToKill.get(i);
11252                    Slog.i(TAG, "Removing system update proc: " + proc);
11253                    removeProcessLocked(proc, true, false, "system update done");
11254                }
11255            }
11256
11257            // Now that we have cleaned up any update processes, we
11258            // are ready to start launching real processes and know that
11259            // we won't trample on them any more.
11260            mProcessesReady = true;
11261        }
11262
11263        Slog.i(TAG, "System now ready");
11264        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11265            SystemClock.uptimeMillis());
11266
11267        synchronized(this) {
11268            // Make sure we have no pre-ready processes sitting around.
11269
11270            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11271                ResolveInfo ri = mContext.getPackageManager()
11272                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11273                                STOCK_PM_FLAGS);
11274                CharSequence errorMsg = null;
11275                if (ri != null) {
11276                    ActivityInfo ai = ri.activityInfo;
11277                    ApplicationInfo app = ai.applicationInfo;
11278                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11279                        mTopAction = Intent.ACTION_FACTORY_TEST;
11280                        mTopData = null;
11281                        mTopComponent = new ComponentName(app.packageName,
11282                                ai.name);
11283                    } else {
11284                        errorMsg = mContext.getResources().getText(
11285                                com.android.internal.R.string.factorytest_not_system);
11286                    }
11287                } else {
11288                    errorMsg = mContext.getResources().getText(
11289                            com.android.internal.R.string.factorytest_no_action);
11290                }
11291                if (errorMsg != null) {
11292                    mTopAction = null;
11293                    mTopData = null;
11294                    mTopComponent = null;
11295                    Message msg = Message.obtain();
11296                    msg.what = SHOW_FACTORY_ERROR_MSG;
11297                    msg.getData().putCharSequence("msg", errorMsg);
11298                    mHandler.sendMessage(msg);
11299                }
11300            }
11301        }
11302
11303        retrieveSettings();
11304        loadResourcesOnSystemReady();
11305
11306        synchronized (this) {
11307            readGrantedUriPermissionsLocked();
11308        }
11309
11310        if (goingCallback != null) goingCallback.run();
11311
11312        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11313                Integer.toString(mCurrentUserId), mCurrentUserId);
11314        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11315                Integer.toString(mCurrentUserId), mCurrentUserId);
11316        mSystemServiceManager.startUser(mCurrentUserId);
11317
11318        synchronized (this) {
11319            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11320                try {
11321                    List apps = AppGlobals.getPackageManager().
11322                        getPersistentApplications(STOCK_PM_FLAGS);
11323                    if (apps != null) {
11324                        int N = apps.size();
11325                        int i;
11326                        for (i=0; i<N; i++) {
11327                            ApplicationInfo info
11328                                = (ApplicationInfo)apps.get(i);
11329                            if (info != null &&
11330                                    !info.packageName.equals("android")) {
11331                                addAppLocked(info, false, null /* ABI override */);
11332                            }
11333                        }
11334                    }
11335                } catch (RemoteException ex) {
11336                    // pm is in same process, this will never happen.
11337                }
11338            }
11339
11340            // Start up initial activity.
11341            mBooting = true;
11342            startHomeActivityLocked(mCurrentUserId, "systemReady");
11343
11344            try {
11345                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11346                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11347                            + " data partition or your device will be unstable.");
11348                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11349                }
11350            } catch (RemoteException e) {
11351            }
11352
11353            if (!Build.isFingerprintConsistent()) {
11354                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11355                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11356            }
11357
11358            long ident = Binder.clearCallingIdentity();
11359            try {
11360                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11361                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11362                        | Intent.FLAG_RECEIVER_FOREGROUND);
11363                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11364                broadcastIntentLocked(null, null, intent,
11365                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11366                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11367                intent = new Intent(Intent.ACTION_USER_STARTING);
11368                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11369                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11370                broadcastIntentLocked(null, null, intent,
11371                        null, new IIntentReceiver.Stub() {
11372                            @Override
11373                            public void performReceive(Intent intent, int resultCode, String data,
11374                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11375                                    throws RemoteException {
11376                            }
11377                        }, 0, null, null,
11378                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11379                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11380            } catch (Throwable t) {
11381                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11382            } finally {
11383                Binder.restoreCallingIdentity(ident);
11384            }
11385            mStackSupervisor.resumeTopActivitiesLocked();
11386            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11387        }
11388    }
11389
11390    private boolean makeAppCrashingLocked(ProcessRecord app,
11391            String shortMsg, String longMsg, String stackTrace) {
11392        app.crashing = true;
11393        app.crashingReport = generateProcessError(app,
11394                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11395        startAppProblemLocked(app);
11396        app.stopFreezingAllLocked();
11397        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11398    }
11399
11400    private void makeAppNotRespondingLocked(ProcessRecord app,
11401            String activity, String shortMsg, String longMsg) {
11402        app.notResponding = true;
11403        app.notRespondingReport = generateProcessError(app,
11404                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11405                activity, shortMsg, longMsg, null);
11406        startAppProblemLocked(app);
11407        app.stopFreezingAllLocked();
11408    }
11409
11410    /**
11411     * Generate a process error record, suitable for attachment to a ProcessRecord.
11412     *
11413     * @param app The ProcessRecord in which the error occurred.
11414     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11415     *                      ActivityManager.AppErrorStateInfo
11416     * @param activity The activity associated with the crash, if known.
11417     * @param shortMsg Short message describing the crash.
11418     * @param longMsg Long message describing the crash.
11419     * @param stackTrace Full crash stack trace, may be null.
11420     *
11421     * @return Returns a fully-formed AppErrorStateInfo record.
11422     */
11423    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11424            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11425        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11426
11427        report.condition = condition;
11428        report.processName = app.processName;
11429        report.pid = app.pid;
11430        report.uid = app.info.uid;
11431        report.tag = activity;
11432        report.shortMsg = shortMsg;
11433        report.longMsg = longMsg;
11434        report.stackTrace = stackTrace;
11435
11436        return report;
11437    }
11438
11439    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11440        synchronized (this) {
11441            app.crashing = false;
11442            app.crashingReport = null;
11443            app.notResponding = false;
11444            app.notRespondingReport = null;
11445            if (app.anrDialog == fromDialog) {
11446                app.anrDialog = null;
11447            }
11448            if (app.waitDialog == fromDialog) {
11449                app.waitDialog = null;
11450            }
11451            if (app.pid > 0 && app.pid != MY_PID) {
11452                handleAppCrashLocked(app, null, null, null);
11453                app.kill("user request after error", true);
11454            }
11455        }
11456    }
11457
11458    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11459            String stackTrace) {
11460        long now = SystemClock.uptimeMillis();
11461
11462        Long crashTime;
11463        if (!app.isolated) {
11464            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11465        } else {
11466            crashTime = null;
11467        }
11468        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11469            // This process loses!
11470            Slog.w(TAG, "Process " + app.info.processName
11471                    + " has crashed too many times: killing!");
11472            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11473                    app.userId, app.info.processName, app.uid);
11474            mStackSupervisor.handleAppCrashLocked(app);
11475            if (!app.persistent) {
11476                // We don't want to start this process again until the user
11477                // explicitly does so...  but for persistent process, we really
11478                // need to keep it running.  If a persistent process is actually
11479                // repeatedly crashing, then badness for everyone.
11480                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11481                        app.info.processName);
11482                if (!app.isolated) {
11483                    // XXX We don't have a way to mark isolated processes
11484                    // as bad, since they don't have a peristent identity.
11485                    mBadProcesses.put(app.info.processName, app.uid,
11486                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11487                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11488                }
11489                app.bad = true;
11490                app.removed = true;
11491                // Don't let services in this process be restarted and potentially
11492                // annoy the user repeatedly.  Unless it is persistent, since those
11493                // processes run critical code.
11494                removeProcessLocked(app, false, false, "crash");
11495                mStackSupervisor.resumeTopActivitiesLocked();
11496                return false;
11497            }
11498            mStackSupervisor.resumeTopActivitiesLocked();
11499        } else {
11500            mStackSupervisor.finishTopRunningActivityLocked(app);
11501        }
11502
11503        // Bump up the crash count of any services currently running in the proc.
11504        for (int i=app.services.size()-1; i>=0; i--) {
11505            // Any services running in the application need to be placed
11506            // back in the pending list.
11507            ServiceRecord sr = app.services.valueAt(i);
11508            sr.crashCount++;
11509        }
11510
11511        // If the crashing process is what we consider to be the "home process" and it has been
11512        // replaced by a third-party app, clear the package preferred activities from packages
11513        // with a home activity running in the process to prevent a repeatedly crashing app
11514        // from blocking the user to manually clear the list.
11515        final ArrayList<ActivityRecord> activities = app.activities;
11516        if (app == mHomeProcess && activities.size() > 0
11517                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11518            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11519                final ActivityRecord r = activities.get(activityNdx);
11520                if (r.isHomeActivity()) {
11521                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11522                    try {
11523                        ActivityThread.getPackageManager()
11524                                .clearPackagePreferredActivities(r.packageName);
11525                    } catch (RemoteException c) {
11526                        // pm is in same process, this will never happen.
11527                    }
11528                }
11529            }
11530        }
11531
11532        if (!app.isolated) {
11533            // XXX Can't keep track of crash times for isolated processes,
11534            // because they don't have a perisistent identity.
11535            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11536        }
11537
11538        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11539        return true;
11540    }
11541
11542    void startAppProblemLocked(ProcessRecord app) {
11543        // If this app is not running under the current user, then we
11544        // can't give it a report button because that would require
11545        // launching the report UI under a different user.
11546        app.errorReportReceiver = null;
11547
11548        for (int userId : mCurrentProfileIds) {
11549            if (app.userId == userId) {
11550                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11551                        mContext, app.info.packageName, app.info.flags);
11552            }
11553        }
11554        skipCurrentReceiverLocked(app);
11555    }
11556
11557    void skipCurrentReceiverLocked(ProcessRecord app) {
11558        for (BroadcastQueue queue : mBroadcastQueues) {
11559            queue.skipCurrentReceiverLocked(app);
11560        }
11561    }
11562
11563    /**
11564     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11565     * The application process will exit immediately after this call returns.
11566     * @param app object of the crashing app, null for the system server
11567     * @param crashInfo describing the exception
11568     */
11569    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11570        ProcessRecord r = findAppProcess(app, "Crash");
11571        final String processName = app == null ? "system_server"
11572                : (r == null ? "unknown" : r.processName);
11573
11574        handleApplicationCrashInner("crash", r, processName, crashInfo);
11575    }
11576
11577    /* Native crash reporting uses this inner version because it needs to be somewhat
11578     * decoupled from the AM-managed cleanup lifecycle
11579     */
11580    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11581            ApplicationErrorReport.CrashInfo crashInfo) {
11582        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11583                UserHandle.getUserId(Binder.getCallingUid()), processName,
11584                r == null ? -1 : r.info.flags,
11585                crashInfo.exceptionClassName,
11586                crashInfo.exceptionMessage,
11587                crashInfo.throwFileName,
11588                crashInfo.throwLineNumber);
11589
11590        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11591
11592        crashApplication(r, crashInfo);
11593    }
11594
11595    public void handleApplicationStrictModeViolation(
11596            IBinder app,
11597            int violationMask,
11598            StrictMode.ViolationInfo info) {
11599        ProcessRecord r = findAppProcess(app, "StrictMode");
11600        if (r == null) {
11601            return;
11602        }
11603
11604        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11605            Integer stackFingerprint = info.hashCode();
11606            boolean logIt = true;
11607            synchronized (mAlreadyLoggedViolatedStacks) {
11608                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11609                    logIt = false;
11610                    // TODO: sub-sample into EventLog for these, with
11611                    // the info.durationMillis?  Then we'd get
11612                    // the relative pain numbers, without logging all
11613                    // the stack traces repeatedly.  We'd want to do
11614                    // likewise in the client code, which also does
11615                    // dup suppression, before the Binder call.
11616                } else {
11617                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11618                        mAlreadyLoggedViolatedStacks.clear();
11619                    }
11620                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11621                }
11622            }
11623            if (logIt) {
11624                logStrictModeViolationToDropBox(r, info);
11625            }
11626        }
11627
11628        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11629            AppErrorResult result = new AppErrorResult();
11630            synchronized (this) {
11631                final long origId = Binder.clearCallingIdentity();
11632
11633                Message msg = Message.obtain();
11634                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11635                HashMap<String, Object> data = new HashMap<String, Object>();
11636                data.put("result", result);
11637                data.put("app", r);
11638                data.put("violationMask", violationMask);
11639                data.put("info", info);
11640                msg.obj = data;
11641                mHandler.sendMessage(msg);
11642
11643                Binder.restoreCallingIdentity(origId);
11644            }
11645            int res = result.get();
11646            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11647        }
11648    }
11649
11650    // Depending on the policy in effect, there could be a bunch of
11651    // these in quick succession so we try to batch these together to
11652    // minimize disk writes, number of dropbox entries, and maximize
11653    // compression, by having more fewer, larger records.
11654    private void logStrictModeViolationToDropBox(
11655            ProcessRecord process,
11656            StrictMode.ViolationInfo info) {
11657        if (info == null) {
11658            return;
11659        }
11660        final boolean isSystemApp = process == null ||
11661                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11662                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11663        final String processName = process == null ? "unknown" : process.processName;
11664        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11665        final DropBoxManager dbox = (DropBoxManager)
11666                mContext.getSystemService(Context.DROPBOX_SERVICE);
11667
11668        // Exit early if the dropbox isn't configured to accept this report type.
11669        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11670
11671        boolean bufferWasEmpty;
11672        boolean needsFlush;
11673        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11674        synchronized (sb) {
11675            bufferWasEmpty = sb.length() == 0;
11676            appendDropBoxProcessHeaders(process, processName, sb);
11677            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11678            sb.append("System-App: ").append(isSystemApp).append("\n");
11679            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11680            if (info.violationNumThisLoop != 0) {
11681                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11682            }
11683            if (info.numAnimationsRunning != 0) {
11684                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11685            }
11686            if (info.broadcastIntentAction != null) {
11687                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11688            }
11689            if (info.durationMillis != -1) {
11690                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11691            }
11692            if (info.numInstances != -1) {
11693                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11694            }
11695            if (info.tags != null) {
11696                for (String tag : info.tags) {
11697                    sb.append("Span-Tag: ").append(tag).append("\n");
11698                }
11699            }
11700            sb.append("\n");
11701            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11702                sb.append(info.crashInfo.stackTrace);
11703            }
11704            sb.append("\n");
11705
11706            // Only buffer up to ~64k.  Various logging bits truncate
11707            // things at 128k.
11708            needsFlush = (sb.length() > 64 * 1024);
11709        }
11710
11711        // Flush immediately if the buffer's grown too large, or this
11712        // is a non-system app.  Non-system apps are isolated with a
11713        // different tag & policy and not batched.
11714        //
11715        // Batching is useful during internal testing with
11716        // StrictMode settings turned up high.  Without batching,
11717        // thousands of separate files could be created on boot.
11718        if (!isSystemApp || needsFlush) {
11719            new Thread("Error dump: " + dropboxTag) {
11720                @Override
11721                public void run() {
11722                    String report;
11723                    synchronized (sb) {
11724                        report = sb.toString();
11725                        sb.delete(0, sb.length());
11726                        sb.trimToSize();
11727                    }
11728                    if (report.length() != 0) {
11729                        dbox.addText(dropboxTag, report);
11730                    }
11731                }
11732            }.start();
11733            return;
11734        }
11735
11736        // System app batching:
11737        if (!bufferWasEmpty) {
11738            // An existing dropbox-writing thread is outstanding, so
11739            // we don't need to start it up.  The existing thread will
11740            // catch the buffer appends we just did.
11741            return;
11742        }
11743
11744        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11745        // (After this point, we shouldn't access AMS internal data structures.)
11746        new Thread("Error dump: " + dropboxTag) {
11747            @Override
11748            public void run() {
11749                // 5 second sleep to let stacks arrive and be batched together
11750                try {
11751                    Thread.sleep(5000);  // 5 seconds
11752                } catch (InterruptedException e) {}
11753
11754                String errorReport;
11755                synchronized (mStrictModeBuffer) {
11756                    errorReport = mStrictModeBuffer.toString();
11757                    if (errorReport.length() == 0) {
11758                        return;
11759                    }
11760                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11761                    mStrictModeBuffer.trimToSize();
11762                }
11763                dbox.addText(dropboxTag, errorReport);
11764            }
11765        }.start();
11766    }
11767
11768    /**
11769     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11770     * @param app object of the crashing app, null for the system server
11771     * @param tag reported by the caller
11772     * @param system whether this wtf is coming from the system
11773     * @param crashInfo describing the context of the error
11774     * @return true if the process should exit immediately (WTF is fatal)
11775     */
11776    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11777            final ApplicationErrorReport.CrashInfo crashInfo) {
11778        final int callingUid = Binder.getCallingUid();
11779        final int callingPid = Binder.getCallingPid();
11780
11781        if (system) {
11782            // If this is coming from the system, we could very well have low-level
11783            // system locks held, so we want to do this all asynchronously.  And we
11784            // never want this to become fatal, so there is that too.
11785            mHandler.post(new Runnable() {
11786                @Override public void run() {
11787                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11788                }
11789            });
11790            return false;
11791        }
11792
11793        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11794                crashInfo);
11795
11796        if (r != null && r.pid != Process.myPid() &&
11797                Settings.Global.getInt(mContext.getContentResolver(),
11798                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11799            crashApplication(r, crashInfo);
11800            return true;
11801        } else {
11802            return false;
11803        }
11804    }
11805
11806    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11807            final ApplicationErrorReport.CrashInfo crashInfo) {
11808        final ProcessRecord r = findAppProcess(app, "WTF");
11809        final String processName = app == null ? "system_server"
11810                : (r == null ? "unknown" : r.processName);
11811
11812        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11813                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11814
11815        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11816
11817        return r;
11818    }
11819
11820    /**
11821     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11822     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11823     */
11824    private ProcessRecord findAppProcess(IBinder app, String reason) {
11825        if (app == null) {
11826            return null;
11827        }
11828
11829        synchronized (this) {
11830            final int NP = mProcessNames.getMap().size();
11831            for (int ip=0; ip<NP; ip++) {
11832                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11833                final int NA = apps.size();
11834                for (int ia=0; ia<NA; ia++) {
11835                    ProcessRecord p = apps.valueAt(ia);
11836                    if (p.thread != null && p.thread.asBinder() == app) {
11837                        return p;
11838                    }
11839                }
11840            }
11841
11842            Slog.w(TAG, "Can't find mystery application for " + reason
11843                    + " from pid=" + Binder.getCallingPid()
11844                    + " uid=" + Binder.getCallingUid() + ": " + app);
11845            return null;
11846        }
11847    }
11848
11849    /**
11850     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11851     * to append various headers to the dropbox log text.
11852     */
11853    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11854            StringBuilder sb) {
11855        // Watchdog thread ends up invoking this function (with
11856        // a null ProcessRecord) to add the stack file to dropbox.
11857        // Do not acquire a lock on this (am) in such cases, as it
11858        // could cause a potential deadlock, if and when watchdog
11859        // is invoked due to unavailability of lock on am and it
11860        // would prevent watchdog from killing system_server.
11861        if (process == null) {
11862            sb.append("Process: ").append(processName).append("\n");
11863            return;
11864        }
11865        // Note: ProcessRecord 'process' is guarded by the service
11866        // instance.  (notably process.pkgList, which could otherwise change
11867        // concurrently during execution of this method)
11868        synchronized (this) {
11869            sb.append("Process: ").append(processName).append("\n");
11870            int flags = process.info.flags;
11871            IPackageManager pm = AppGlobals.getPackageManager();
11872            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11873            for (int ip=0; ip<process.pkgList.size(); ip++) {
11874                String pkg = process.pkgList.keyAt(ip);
11875                sb.append("Package: ").append(pkg);
11876                try {
11877                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11878                    if (pi != null) {
11879                        sb.append(" v").append(pi.versionCode);
11880                        if (pi.versionName != null) {
11881                            sb.append(" (").append(pi.versionName).append(")");
11882                        }
11883                    }
11884                } catch (RemoteException e) {
11885                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11886                }
11887                sb.append("\n");
11888            }
11889        }
11890    }
11891
11892    private static String processClass(ProcessRecord process) {
11893        if (process == null || process.pid == MY_PID) {
11894            return "system_server";
11895        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11896            return "system_app";
11897        } else {
11898            return "data_app";
11899        }
11900    }
11901
11902    /**
11903     * Write a description of an error (crash, WTF, ANR) to the drop box.
11904     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11905     * @param process which caused the error, null means the system server
11906     * @param activity which triggered the error, null if unknown
11907     * @param parent activity related to the error, null if unknown
11908     * @param subject line related to the error, null if absent
11909     * @param report in long form describing the error, null if absent
11910     * @param logFile to include in the report, null if none
11911     * @param crashInfo giving an application stack trace, null if absent
11912     */
11913    public void addErrorToDropBox(String eventType,
11914            ProcessRecord process, String processName, ActivityRecord activity,
11915            ActivityRecord parent, String subject,
11916            final String report, final File logFile,
11917            final ApplicationErrorReport.CrashInfo crashInfo) {
11918        // NOTE -- this must never acquire the ActivityManagerService lock,
11919        // otherwise the watchdog may be prevented from resetting the system.
11920
11921        final String dropboxTag = processClass(process) + "_" + eventType;
11922        final DropBoxManager dbox = (DropBoxManager)
11923                mContext.getSystemService(Context.DROPBOX_SERVICE);
11924
11925        // Exit early if the dropbox isn't configured to accept this report type.
11926        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11927
11928        final StringBuilder sb = new StringBuilder(1024);
11929        appendDropBoxProcessHeaders(process, processName, sb);
11930        if (activity != null) {
11931            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11932        }
11933        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11934            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11935        }
11936        if (parent != null && parent != activity) {
11937            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11938        }
11939        if (subject != null) {
11940            sb.append("Subject: ").append(subject).append("\n");
11941        }
11942        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11943        if (Debug.isDebuggerConnected()) {
11944            sb.append("Debugger: Connected\n");
11945        }
11946        sb.append("\n");
11947
11948        // Do the rest in a worker thread to avoid blocking the caller on I/O
11949        // (After this point, we shouldn't access AMS internal data structures.)
11950        Thread worker = new Thread("Error dump: " + dropboxTag) {
11951            @Override
11952            public void run() {
11953                if (report != null) {
11954                    sb.append(report);
11955                }
11956                if (logFile != null) {
11957                    try {
11958                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11959                                    "\n\n[[TRUNCATED]]"));
11960                    } catch (IOException e) {
11961                        Slog.e(TAG, "Error reading " + logFile, e);
11962                    }
11963                }
11964                if (crashInfo != null && crashInfo.stackTrace != null) {
11965                    sb.append(crashInfo.stackTrace);
11966                }
11967
11968                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11969                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11970                if (lines > 0) {
11971                    sb.append("\n");
11972
11973                    // Merge several logcat streams, and take the last N lines
11974                    InputStreamReader input = null;
11975                    try {
11976                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11977                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11978                                "-b", "crash",
11979                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11980
11981                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11982                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11983                        input = new InputStreamReader(logcat.getInputStream());
11984
11985                        int num;
11986                        char[] buf = new char[8192];
11987                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11988                    } catch (IOException e) {
11989                        Slog.e(TAG, "Error running logcat", e);
11990                    } finally {
11991                        if (input != null) try { input.close(); } catch (IOException e) {}
11992                    }
11993                }
11994
11995                dbox.addText(dropboxTag, sb.toString());
11996            }
11997        };
11998
11999        if (process == null) {
12000            // If process is null, we are being called from some internal code
12001            // and may be about to die -- run this synchronously.
12002            worker.run();
12003        } else {
12004            worker.start();
12005        }
12006    }
12007
12008    /**
12009     * Bring up the "unexpected error" dialog box for a crashing app.
12010     * Deal with edge cases (intercepts from instrumented applications,
12011     * ActivityController, error intent receivers, that sort of thing).
12012     * @param r the application crashing
12013     * @param crashInfo describing the failure
12014     */
12015    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12016        long timeMillis = System.currentTimeMillis();
12017        String shortMsg = crashInfo.exceptionClassName;
12018        String longMsg = crashInfo.exceptionMessage;
12019        String stackTrace = crashInfo.stackTrace;
12020        if (shortMsg != null && longMsg != null) {
12021            longMsg = shortMsg + ": " + longMsg;
12022        } else if (shortMsg != null) {
12023            longMsg = shortMsg;
12024        }
12025
12026        AppErrorResult result = new AppErrorResult();
12027        synchronized (this) {
12028            if (mController != null) {
12029                try {
12030                    String name = r != null ? r.processName : null;
12031                    int pid = r != null ? r.pid : Binder.getCallingPid();
12032                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12033                    if (!mController.appCrashed(name, pid,
12034                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12035                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12036                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12037                            Slog.w(TAG, "Skip killing native crashed app " + name
12038                                    + "(" + pid + ") during testing");
12039                        } else {
12040                            Slog.w(TAG, "Force-killing crashed app " + name
12041                                    + " at watcher's request");
12042                            if (r != null) {
12043                                r.kill("crash", true);
12044                            } else {
12045                                // Huh.
12046                                Process.killProcess(pid);
12047                                Process.killProcessGroup(uid, pid);
12048                            }
12049                        }
12050                        return;
12051                    }
12052                } catch (RemoteException e) {
12053                    mController = null;
12054                    Watchdog.getInstance().setActivityController(null);
12055                }
12056            }
12057
12058            final long origId = Binder.clearCallingIdentity();
12059
12060            // If this process is running instrumentation, finish it.
12061            if (r != null && r.instrumentationClass != null) {
12062                Slog.w(TAG, "Error in app " + r.processName
12063                      + " running instrumentation " + r.instrumentationClass + ":");
12064                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12065                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12066                Bundle info = new Bundle();
12067                info.putString("shortMsg", shortMsg);
12068                info.putString("longMsg", longMsg);
12069                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12070                Binder.restoreCallingIdentity(origId);
12071                return;
12072            }
12073
12074            // Log crash in battery stats.
12075            if (r != null) {
12076                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12077            }
12078
12079            // If we can't identify the process or it's already exceeded its crash quota,
12080            // quit right away without showing a crash dialog.
12081            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12082                Binder.restoreCallingIdentity(origId);
12083                return;
12084            }
12085
12086            Message msg = Message.obtain();
12087            msg.what = SHOW_ERROR_MSG;
12088            HashMap data = new HashMap();
12089            data.put("result", result);
12090            data.put("app", r);
12091            msg.obj = data;
12092            mHandler.sendMessage(msg);
12093
12094            Binder.restoreCallingIdentity(origId);
12095        }
12096
12097        int res = result.get();
12098
12099        Intent appErrorIntent = null;
12100        synchronized (this) {
12101            if (r != null && !r.isolated) {
12102                // XXX Can't keep track of crash time for isolated processes,
12103                // since they don't have a persistent identity.
12104                mProcessCrashTimes.put(r.info.processName, r.uid,
12105                        SystemClock.uptimeMillis());
12106            }
12107            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12108                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12109            }
12110        }
12111
12112        if (appErrorIntent != null) {
12113            try {
12114                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12115            } catch (ActivityNotFoundException e) {
12116                Slog.w(TAG, "bug report receiver dissappeared", e);
12117            }
12118        }
12119    }
12120
12121    Intent createAppErrorIntentLocked(ProcessRecord r,
12122            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12123        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12124        if (report == null) {
12125            return null;
12126        }
12127        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12128        result.setComponent(r.errorReportReceiver);
12129        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12130        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12131        return result;
12132    }
12133
12134    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12135            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12136        if (r.errorReportReceiver == null) {
12137            return null;
12138        }
12139
12140        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12141            return null;
12142        }
12143
12144        ApplicationErrorReport report = new ApplicationErrorReport();
12145        report.packageName = r.info.packageName;
12146        report.installerPackageName = r.errorReportReceiver.getPackageName();
12147        report.processName = r.processName;
12148        report.time = timeMillis;
12149        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12150
12151        if (r.crashing || r.forceCrashReport) {
12152            report.type = ApplicationErrorReport.TYPE_CRASH;
12153            report.crashInfo = crashInfo;
12154        } else if (r.notResponding) {
12155            report.type = ApplicationErrorReport.TYPE_ANR;
12156            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12157
12158            report.anrInfo.activity = r.notRespondingReport.tag;
12159            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12160            report.anrInfo.info = r.notRespondingReport.longMsg;
12161        }
12162
12163        return report;
12164    }
12165
12166    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12167        enforceNotIsolatedCaller("getProcessesInErrorState");
12168        // assume our apps are happy - lazy create the list
12169        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12170
12171        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12172                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12173        int userId = UserHandle.getUserId(Binder.getCallingUid());
12174
12175        synchronized (this) {
12176
12177            // iterate across all processes
12178            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12179                ProcessRecord app = mLruProcesses.get(i);
12180                if (!allUsers && app.userId != userId) {
12181                    continue;
12182                }
12183                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12184                    // This one's in trouble, so we'll generate a report for it
12185                    // crashes are higher priority (in case there's a crash *and* an anr)
12186                    ActivityManager.ProcessErrorStateInfo report = null;
12187                    if (app.crashing) {
12188                        report = app.crashingReport;
12189                    } else if (app.notResponding) {
12190                        report = app.notRespondingReport;
12191                    }
12192
12193                    if (report != null) {
12194                        if (errList == null) {
12195                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12196                        }
12197                        errList.add(report);
12198                    } else {
12199                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12200                                " crashing = " + app.crashing +
12201                                " notResponding = " + app.notResponding);
12202                    }
12203                }
12204            }
12205        }
12206
12207        return errList;
12208    }
12209
12210    static int procStateToImportance(int procState, int memAdj,
12211            ActivityManager.RunningAppProcessInfo currApp) {
12212        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12213        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12214            currApp.lru = memAdj;
12215        } else {
12216            currApp.lru = 0;
12217        }
12218        return imp;
12219    }
12220
12221    private void fillInProcMemInfo(ProcessRecord app,
12222            ActivityManager.RunningAppProcessInfo outInfo) {
12223        outInfo.pid = app.pid;
12224        outInfo.uid = app.info.uid;
12225        if (mHeavyWeightProcess == app) {
12226            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12227        }
12228        if (app.persistent) {
12229            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12230        }
12231        if (app.activities.size() > 0) {
12232            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12233        }
12234        outInfo.lastTrimLevel = app.trimMemoryLevel;
12235        int adj = app.curAdj;
12236        int procState = app.curProcState;
12237        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12238        outInfo.importanceReasonCode = app.adjTypeCode;
12239        outInfo.processState = app.curProcState;
12240    }
12241
12242    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12243        enforceNotIsolatedCaller("getRunningAppProcesses");
12244        // Lazy instantiation of list
12245        List<ActivityManager.RunningAppProcessInfo> runList = null;
12246        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12247                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12248        int userId = UserHandle.getUserId(Binder.getCallingUid());
12249        synchronized (this) {
12250            // Iterate across all processes
12251            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12252                ProcessRecord app = mLruProcesses.get(i);
12253                if (!allUsers && app.userId != userId) {
12254                    continue;
12255                }
12256                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12257                    // Generate process state info for running application
12258                    ActivityManager.RunningAppProcessInfo currApp =
12259                        new ActivityManager.RunningAppProcessInfo(app.processName,
12260                                app.pid, app.getPackageList());
12261                    fillInProcMemInfo(app, currApp);
12262                    if (app.adjSource instanceof ProcessRecord) {
12263                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12264                        currApp.importanceReasonImportance =
12265                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12266                                        app.adjSourceProcState);
12267                    } else if (app.adjSource instanceof ActivityRecord) {
12268                        ActivityRecord r = (ActivityRecord)app.adjSource;
12269                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12270                    }
12271                    if (app.adjTarget instanceof ComponentName) {
12272                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12273                    }
12274                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12275                    //        + " lru=" + currApp.lru);
12276                    if (runList == null) {
12277                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12278                    }
12279                    runList.add(currApp);
12280                }
12281            }
12282        }
12283        return runList;
12284    }
12285
12286    public List<ApplicationInfo> getRunningExternalApplications() {
12287        enforceNotIsolatedCaller("getRunningExternalApplications");
12288        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12289        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12290        if (runningApps != null && runningApps.size() > 0) {
12291            Set<String> extList = new HashSet<String>();
12292            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12293                if (app.pkgList != null) {
12294                    for (String pkg : app.pkgList) {
12295                        extList.add(pkg);
12296                    }
12297                }
12298            }
12299            IPackageManager pm = AppGlobals.getPackageManager();
12300            for (String pkg : extList) {
12301                try {
12302                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12303                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12304                        retList.add(info);
12305                    }
12306                } catch (RemoteException e) {
12307                }
12308            }
12309        }
12310        return retList;
12311    }
12312
12313    @Override
12314    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12315        enforceNotIsolatedCaller("getMyMemoryState");
12316        synchronized (this) {
12317            ProcessRecord proc;
12318            synchronized (mPidsSelfLocked) {
12319                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12320            }
12321            fillInProcMemInfo(proc, outInfo);
12322        }
12323    }
12324
12325    @Override
12326    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12327        if (checkCallingPermission(android.Manifest.permission.DUMP)
12328                != PackageManager.PERMISSION_GRANTED) {
12329            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12330                    + Binder.getCallingPid()
12331                    + ", uid=" + Binder.getCallingUid()
12332                    + " without permission "
12333                    + android.Manifest.permission.DUMP);
12334            return;
12335        }
12336
12337        boolean dumpAll = false;
12338        boolean dumpClient = false;
12339        String dumpPackage = null;
12340
12341        int opti = 0;
12342        while (opti < args.length) {
12343            String opt = args[opti];
12344            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12345                break;
12346            }
12347            opti++;
12348            if ("-a".equals(opt)) {
12349                dumpAll = true;
12350            } else if ("-c".equals(opt)) {
12351                dumpClient = true;
12352            } else if ("-p".equals(opt)) {
12353                if (opti < args.length) {
12354                    dumpPackage = args[opti];
12355                    opti++;
12356                } else {
12357                    pw.println("Error: -p option requires package argument");
12358                    return;
12359                }
12360                dumpClient = true;
12361            } else if ("-h".equals(opt)) {
12362                pw.println("Activity manager dump options:");
12363                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12364                pw.println("  cmd may be one of:");
12365                pw.println("    a[ctivities]: activity stack state");
12366                pw.println("    r[recents]: recent activities state");
12367                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12368                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12369                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12370                pw.println("    o[om]: out of memory management");
12371                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12372                pw.println("    provider [COMP_SPEC]: provider client-side state");
12373                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12374                pw.println("    as[sociations]: tracked app associations");
12375                pw.println("    service [COMP_SPEC]: service client-side state");
12376                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12377                pw.println("    all: dump all activities");
12378                pw.println("    top: dump the top activity");
12379                pw.println("    write: write all pending state to storage");
12380                pw.println("    track-associations: enable association tracking");
12381                pw.println("    untrack-associations: disable and clear association tracking");
12382                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12383                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12384                pw.println("    a partial substring in a component name, a");
12385                pw.println("    hex object identifier.");
12386                pw.println("  -a: include all available server state.");
12387                pw.println("  -c: include client state.");
12388                pw.println("  -p: limit output to given package.");
12389                return;
12390            } else {
12391                pw.println("Unknown argument: " + opt + "; use -h for help");
12392            }
12393        }
12394
12395        long origId = Binder.clearCallingIdentity();
12396        boolean more = false;
12397        // Is the caller requesting to dump a particular piece of data?
12398        if (opti < args.length) {
12399            String cmd = args[opti];
12400            opti++;
12401            if ("activities".equals(cmd) || "a".equals(cmd)) {
12402                synchronized (this) {
12403                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12404                }
12405            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12406                synchronized (this) {
12407                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12408                }
12409            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12410                String[] newArgs;
12411                String name;
12412                if (opti >= args.length) {
12413                    name = null;
12414                    newArgs = EMPTY_STRING_ARRAY;
12415                } else {
12416                    dumpPackage = args[opti];
12417                    opti++;
12418                    newArgs = new String[args.length - opti];
12419                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12420                            args.length - opti);
12421                }
12422                synchronized (this) {
12423                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12424                }
12425            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12426                String[] newArgs;
12427                String name;
12428                if (opti >= args.length) {
12429                    name = null;
12430                    newArgs = EMPTY_STRING_ARRAY;
12431                } else {
12432                    dumpPackage = args[opti];
12433                    opti++;
12434                    newArgs = new String[args.length - opti];
12435                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12436                            args.length - opti);
12437                }
12438                synchronized (this) {
12439                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12440                }
12441            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12442                String[] newArgs;
12443                String name;
12444                if (opti >= args.length) {
12445                    name = null;
12446                    newArgs = EMPTY_STRING_ARRAY;
12447                } else {
12448                    dumpPackage = args[opti];
12449                    opti++;
12450                    newArgs = new String[args.length - opti];
12451                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12452                            args.length - opti);
12453                }
12454                synchronized (this) {
12455                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12456                }
12457            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12458                synchronized (this) {
12459                    dumpOomLocked(fd, pw, args, opti, true);
12460                }
12461            } else if ("provider".equals(cmd)) {
12462                String[] newArgs;
12463                String name;
12464                if (opti >= args.length) {
12465                    name = null;
12466                    newArgs = EMPTY_STRING_ARRAY;
12467                } else {
12468                    name = args[opti];
12469                    opti++;
12470                    newArgs = new String[args.length - opti];
12471                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12472                }
12473                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12474                    pw.println("No providers match: " + name);
12475                    pw.println("Use -h for help.");
12476                }
12477            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12478                synchronized (this) {
12479                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12480                }
12481            } else if ("service".equals(cmd)) {
12482                String[] newArgs;
12483                String name;
12484                if (opti >= args.length) {
12485                    name = null;
12486                    newArgs = EMPTY_STRING_ARRAY;
12487                } else {
12488                    name = args[opti];
12489                    opti++;
12490                    newArgs = new String[args.length - opti];
12491                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12492                            args.length - opti);
12493                }
12494                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12495                    pw.println("No services match: " + name);
12496                    pw.println("Use -h for help.");
12497                }
12498            } else if ("package".equals(cmd)) {
12499                String[] newArgs;
12500                if (opti >= args.length) {
12501                    pw.println("package: no package name specified");
12502                    pw.println("Use -h for help.");
12503                } else {
12504                    dumpPackage = args[opti];
12505                    opti++;
12506                    newArgs = new String[args.length - opti];
12507                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12508                            args.length - opti);
12509                    args = newArgs;
12510                    opti = 0;
12511                    more = true;
12512                }
12513            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12514                synchronized (this) {
12515                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12516                }
12517            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12518                synchronized (this) {
12519                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12520                }
12521            } else if ("write".equals(cmd)) {
12522                mTaskPersister.flush();
12523                pw.println("All tasks persisted.");
12524                return;
12525            } else if ("track-associations".equals(cmd)) {
12526                synchronized (this) {
12527                    if (!mTrackingAssociations) {
12528                        mTrackingAssociations = true;
12529                        pw.println("Association tracking started.");
12530                    } else {
12531                        pw.println("Association tracking already enabled.");
12532                    }
12533                }
12534                return;
12535            } else if ("untrack-associations".equals(cmd)) {
12536                synchronized (this) {
12537                    if (mTrackingAssociations) {
12538                        mTrackingAssociations = false;
12539                        mAssociations.clear();
12540                        pw.println("Association tracking stopped.");
12541                    } else {
12542                        pw.println("Association tracking not running.");
12543                    }
12544                }
12545                return;
12546            } else {
12547                // Dumping a single activity?
12548                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12549                    pw.println("Bad activity command, or no activities match: " + cmd);
12550                    pw.println("Use -h for help.");
12551                }
12552            }
12553            if (!more) {
12554                Binder.restoreCallingIdentity(origId);
12555                return;
12556            }
12557        }
12558
12559        // No piece of data specified, dump everything.
12560        synchronized (this) {
12561            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12562            pw.println();
12563            if (dumpAll) {
12564                pw.println("-------------------------------------------------------------------------------");
12565            }
12566            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12567            pw.println();
12568            if (dumpAll) {
12569                pw.println("-------------------------------------------------------------------------------");
12570            }
12571            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12572            pw.println();
12573            if (dumpAll) {
12574                pw.println("-------------------------------------------------------------------------------");
12575            }
12576            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12577            pw.println();
12578            if (dumpAll) {
12579                pw.println("-------------------------------------------------------------------------------");
12580            }
12581            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12582            pw.println();
12583            if (dumpAll) {
12584                pw.println("-------------------------------------------------------------------------------");
12585            }
12586            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12587            if (mAssociations.size() > 0) {
12588                pw.println();
12589                if (dumpAll) {
12590                    pw.println("-------------------------------------------------------------------------------");
12591                }
12592                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12593            }
12594            pw.println();
12595            if (dumpAll) {
12596                pw.println("-------------------------------------------------------------------------------");
12597            }
12598            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12599        }
12600        Binder.restoreCallingIdentity(origId);
12601    }
12602
12603    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12604            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12605        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12606
12607        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12608                dumpPackage);
12609        boolean needSep = printedAnything;
12610
12611        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12612                dumpPackage, needSep, "  mFocusedActivity: ");
12613        if (printed) {
12614            printedAnything = true;
12615            needSep = false;
12616        }
12617
12618        if (dumpPackage == null) {
12619            if (needSep) {
12620                pw.println();
12621            }
12622            needSep = true;
12623            printedAnything = true;
12624            mStackSupervisor.dump(pw, "  ");
12625        }
12626
12627        if (!printedAnything) {
12628            pw.println("  (nothing)");
12629        }
12630    }
12631
12632    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12633            int opti, boolean dumpAll, String dumpPackage) {
12634        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12635
12636        boolean printedAnything = false;
12637
12638        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12639            boolean printedHeader = false;
12640
12641            final int N = mRecentTasks.size();
12642            for (int i=0; i<N; i++) {
12643                TaskRecord tr = mRecentTasks.get(i);
12644                if (dumpPackage != null) {
12645                    if (tr.realActivity == null ||
12646                            !dumpPackage.equals(tr.realActivity)) {
12647                        continue;
12648                    }
12649                }
12650                if (!printedHeader) {
12651                    pw.println("  Recent tasks:");
12652                    printedHeader = true;
12653                    printedAnything = true;
12654                }
12655                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12656                        pw.println(tr);
12657                if (dumpAll) {
12658                    mRecentTasks.get(i).dump(pw, "    ");
12659                }
12660            }
12661        }
12662
12663        if (!printedAnything) {
12664            pw.println("  (nothing)");
12665        }
12666    }
12667
12668    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12669            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12670        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12671
12672        int dumpUid = 0;
12673        if (dumpPackage != null) {
12674            IPackageManager pm = AppGlobals.getPackageManager();
12675            try {
12676                dumpUid = pm.getPackageUid(dumpPackage, 0);
12677            } catch (RemoteException e) {
12678            }
12679        }
12680
12681        boolean printedAnything = false;
12682
12683        final long now = SystemClock.uptimeMillis();
12684
12685        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12686            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12687                    = mAssociations.valueAt(i1);
12688            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12689                SparseArray<ArrayMap<String, Association>> sourceUids
12690                        = targetComponents.valueAt(i2);
12691                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12692                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12693                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12694                        Association ass = sourceProcesses.valueAt(i4);
12695                        if (dumpPackage != null) {
12696                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12697                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12698                                continue;
12699                            }
12700                        }
12701                        printedAnything = true;
12702                        pw.print("  ");
12703                        pw.print(ass.mTargetProcess);
12704                        pw.print("/");
12705                        UserHandle.formatUid(pw, ass.mTargetUid);
12706                        pw.print(" <- ");
12707                        pw.print(ass.mSourceProcess);
12708                        pw.print("/");
12709                        UserHandle.formatUid(pw, ass.mSourceUid);
12710                        pw.println();
12711                        pw.print("    via ");
12712                        pw.print(ass.mTargetComponent.flattenToShortString());
12713                        pw.println();
12714                        pw.print("    ");
12715                        long dur = ass.mTime;
12716                        if (ass.mNesting > 0) {
12717                            dur += now - ass.mStartTime;
12718                        }
12719                        TimeUtils.formatDuration(dur, pw);
12720                        pw.print(" (");
12721                        pw.print(ass.mCount);
12722                        pw.println(" times)");
12723                        if (ass.mNesting > 0) {
12724                            pw.print("    ");
12725                            pw.print(" Currently active: ");
12726                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12727                            pw.println();
12728                        }
12729                    }
12730                }
12731            }
12732
12733        }
12734
12735        if (!printedAnything) {
12736            pw.println("  (nothing)");
12737        }
12738    }
12739
12740    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12741            int opti, boolean dumpAll, String dumpPackage) {
12742        boolean needSep = false;
12743        boolean printedAnything = false;
12744        int numPers = 0;
12745
12746        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12747
12748        if (dumpAll) {
12749            final int NP = mProcessNames.getMap().size();
12750            for (int ip=0; ip<NP; ip++) {
12751                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12752                final int NA = procs.size();
12753                for (int ia=0; ia<NA; ia++) {
12754                    ProcessRecord r = procs.valueAt(ia);
12755                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12756                        continue;
12757                    }
12758                    if (!needSep) {
12759                        pw.println("  All known processes:");
12760                        needSep = true;
12761                        printedAnything = true;
12762                    }
12763                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12764                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12765                        pw.print(" "); pw.println(r);
12766                    r.dump(pw, "    ");
12767                    if (r.persistent) {
12768                        numPers++;
12769                    }
12770                }
12771            }
12772        }
12773
12774        if (mIsolatedProcesses.size() > 0) {
12775            boolean printed = false;
12776            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12777                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12778                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12779                    continue;
12780                }
12781                if (!printed) {
12782                    if (needSep) {
12783                        pw.println();
12784                    }
12785                    pw.println("  Isolated process list (sorted by uid):");
12786                    printedAnything = true;
12787                    printed = true;
12788                    needSep = true;
12789                }
12790                pw.println(String.format("%sIsolated #%2d: %s",
12791                        "    ", i, r.toString()));
12792            }
12793        }
12794
12795        if (mLruProcesses.size() > 0) {
12796            if (needSep) {
12797                pw.println();
12798            }
12799            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12800                    pw.print(" total, non-act at ");
12801                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12802                    pw.print(", non-svc at ");
12803                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12804                    pw.println("):");
12805            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12806            needSep = true;
12807            printedAnything = true;
12808        }
12809
12810        if (dumpAll || dumpPackage != null) {
12811            synchronized (mPidsSelfLocked) {
12812                boolean printed = false;
12813                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12814                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12815                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12816                        continue;
12817                    }
12818                    if (!printed) {
12819                        if (needSep) pw.println();
12820                        needSep = true;
12821                        pw.println("  PID mappings:");
12822                        printed = true;
12823                        printedAnything = true;
12824                    }
12825                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12826                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12827                }
12828            }
12829        }
12830
12831        if (mForegroundProcesses.size() > 0) {
12832            synchronized (mPidsSelfLocked) {
12833                boolean printed = false;
12834                for (int i=0; i<mForegroundProcesses.size(); i++) {
12835                    ProcessRecord r = mPidsSelfLocked.get(
12836                            mForegroundProcesses.valueAt(i).pid);
12837                    if (dumpPackage != null && (r == null
12838                            || !r.pkgList.containsKey(dumpPackage))) {
12839                        continue;
12840                    }
12841                    if (!printed) {
12842                        if (needSep) pw.println();
12843                        needSep = true;
12844                        pw.println("  Foreground Processes:");
12845                        printed = true;
12846                        printedAnything = true;
12847                    }
12848                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12849                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12850                }
12851            }
12852        }
12853
12854        if (mPersistentStartingProcesses.size() > 0) {
12855            if (needSep) pw.println();
12856            needSep = true;
12857            printedAnything = true;
12858            pw.println("  Persisent processes that are starting:");
12859            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12860                    "Starting Norm", "Restarting PERS", dumpPackage);
12861        }
12862
12863        if (mRemovedProcesses.size() > 0) {
12864            if (needSep) pw.println();
12865            needSep = true;
12866            printedAnything = true;
12867            pw.println("  Processes that are being removed:");
12868            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12869                    "Removed Norm", "Removed PERS", dumpPackage);
12870        }
12871
12872        if (mProcessesOnHold.size() > 0) {
12873            if (needSep) pw.println();
12874            needSep = true;
12875            printedAnything = true;
12876            pw.println("  Processes that are on old until the system is ready:");
12877            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12878                    "OnHold Norm", "OnHold PERS", dumpPackage);
12879        }
12880
12881        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12882
12883        if (mProcessCrashTimes.getMap().size() > 0) {
12884            boolean printed = false;
12885            long now = SystemClock.uptimeMillis();
12886            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12887            final int NP = pmap.size();
12888            for (int ip=0; ip<NP; ip++) {
12889                String pname = pmap.keyAt(ip);
12890                SparseArray<Long> uids = pmap.valueAt(ip);
12891                final int N = uids.size();
12892                for (int i=0; i<N; i++) {
12893                    int puid = uids.keyAt(i);
12894                    ProcessRecord r = mProcessNames.get(pname, puid);
12895                    if (dumpPackage != null && (r == null
12896                            || !r.pkgList.containsKey(dumpPackage))) {
12897                        continue;
12898                    }
12899                    if (!printed) {
12900                        if (needSep) pw.println();
12901                        needSep = true;
12902                        pw.println("  Time since processes crashed:");
12903                        printed = true;
12904                        printedAnything = true;
12905                    }
12906                    pw.print("    Process "); pw.print(pname);
12907                            pw.print(" uid "); pw.print(puid);
12908                            pw.print(": last crashed ");
12909                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12910                            pw.println(" ago");
12911                }
12912            }
12913        }
12914
12915        if (mBadProcesses.getMap().size() > 0) {
12916            boolean printed = false;
12917            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12918            final int NP = pmap.size();
12919            for (int ip=0; ip<NP; ip++) {
12920                String pname = pmap.keyAt(ip);
12921                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12922                final int N = uids.size();
12923                for (int i=0; i<N; i++) {
12924                    int puid = uids.keyAt(i);
12925                    ProcessRecord r = mProcessNames.get(pname, puid);
12926                    if (dumpPackage != null && (r == null
12927                            || !r.pkgList.containsKey(dumpPackage))) {
12928                        continue;
12929                    }
12930                    if (!printed) {
12931                        if (needSep) pw.println();
12932                        needSep = true;
12933                        pw.println("  Bad processes:");
12934                        printedAnything = true;
12935                    }
12936                    BadProcessInfo info = uids.valueAt(i);
12937                    pw.print("    Bad process "); pw.print(pname);
12938                            pw.print(" uid "); pw.print(puid);
12939                            pw.print(": crashed at time "); pw.println(info.time);
12940                    if (info.shortMsg != null) {
12941                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12942                    }
12943                    if (info.longMsg != null) {
12944                        pw.print("      Long msg: "); pw.println(info.longMsg);
12945                    }
12946                    if (info.stack != null) {
12947                        pw.println("      Stack:");
12948                        int lastPos = 0;
12949                        for (int pos=0; pos<info.stack.length(); pos++) {
12950                            if (info.stack.charAt(pos) == '\n') {
12951                                pw.print("        ");
12952                                pw.write(info.stack, lastPos, pos-lastPos);
12953                                pw.println();
12954                                lastPos = pos+1;
12955                            }
12956                        }
12957                        if (lastPos < info.stack.length()) {
12958                            pw.print("        ");
12959                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12960                            pw.println();
12961                        }
12962                    }
12963                }
12964            }
12965        }
12966
12967        if (dumpPackage == null) {
12968            pw.println();
12969            needSep = false;
12970            pw.println("  mStartedUsers:");
12971            for (int i=0; i<mStartedUsers.size(); i++) {
12972                UserStartedState uss = mStartedUsers.valueAt(i);
12973                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12974                        pw.print(": "); uss.dump("", pw);
12975            }
12976            pw.print("  mStartedUserArray: [");
12977            for (int i=0; i<mStartedUserArray.length; i++) {
12978                if (i > 0) pw.print(", ");
12979                pw.print(mStartedUserArray[i]);
12980            }
12981            pw.println("]");
12982            pw.print("  mUserLru: [");
12983            for (int i=0; i<mUserLru.size(); i++) {
12984                if (i > 0) pw.print(", ");
12985                pw.print(mUserLru.get(i));
12986            }
12987            pw.println("]");
12988            if (dumpAll) {
12989                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12990            }
12991            synchronized (mUserProfileGroupIdsSelfLocked) {
12992                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12993                    pw.println("  mUserProfileGroupIds:");
12994                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12995                        pw.print("    User #");
12996                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12997                        pw.print(" -> profile #");
12998                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12999                    }
13000                }
13001            }
13002        }
13003        if (mHomeProcess != null && (dumpPackage == null
13004                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13005            if (needSep) {
13006                pw.println();
13007                needSep = false;
13008            }
13009            pw.println("  mHomeProcess: " + mHomeProcess);
13010        }
13011        if (mPreviousProcess != null && (dumpPackage == null
13012                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13013            if (needSep) {
13014                pw.println();
13015                needSep = false;
13016            }
13017            pw.println("  mPreviousProcess: " + mPreviousProcess);
13018        }
13019        if (dumpAll) {
13020            StringBuilder sb = new StringBuilder(128);
13021            sb.append("  mPreviousProcessVisibleTime: ");
13022            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13023            pw.println(sb);
13024        }
13025        if (mHeavyWeightProcess != null && (dumpPackage == null
13026                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13027            if (needSep) {
13028                pw.println();
13029                needSep = false;
13030            }
13031            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13032        }
13033        if (dumpPackage == null) {
13034            pw.println("  mConfiguration: " + mConfiguration);
13035        }
13036        if (dumpAll) {
13037            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13038            if (mCompatModePackages.getPackages().size() > 0) {
13039                boolean printed = false;
13040                for (Map.Entry<String, Integer> entry
13041                        : mCompatModePackages.getPackages().entrySet()) {
13042                    String pkg = entry.getKey();
13043                    int mode = entry.getValue();
13044                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13045                        continue;
13046                    }
13047                    if (!printed) {
13048                        pw.println("  mScreenCompatPackages:");
13049                        printed = true;
13050                    }
13051                    pw.print("    "); pw.print(pkg); pw.print(": ");
13052                            pw.print(mode); pw.println();
13053                }
13054            }
13055        }
13056        if (dumpPackage == null) {
13057            pw.println("  mWakefulness="
13058                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13059            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13060                    + lockScreenShownToString());
13061            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13062                    + " mTestPssMode=" + mTestPssMode);
13063        }
13064        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13065                || mOrigWaitForDebugger) {
13066            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13067                    || dumpPackage.equals(mOrigDebugApp)) {
13068                if (needSep) {
13069                    pw.println();
13070                    needSep = false;
13071                }
13072                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13073                        + " mDebugTransient=" + mDebugTransient
13074                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13075            }
13076        }
13077        if (mOpenGlTraceApp != null) {
13078            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13079                if (needSep) {
13080                    pw.println();
13081                    needSep = false;
13082                }
13083                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13084            }
13085        }
13086        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13087                || mProfileFd != null) {
13088            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13089                if (needSep) {
13090                    pw.println();
13091                    needSep = false;
13092                }
13093                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13094                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13095                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13096                        + mAutoStopProfiler);
13097                pw.println("  mProfileType=" + mProfileType);
13098            }
13099        }
13100        if (dumpPackage == null) {
13101            if (mAlwaysFinishActivities || mController != null) {
13102                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13103                        + " mController=" + mController);
13104            }
13105            if (dumpAll) {
13106                pw.println("  Total persistent processes: " + numPers);
13107                pw.println("  mProcessesReady=" + mProcessesReady
13108                        + " mSystemReady=" + mSystemReady
13109                        + " mBooted=" + mBooted
13110                        + " mFactoryTest=" + mFactoryTest);
13111                pw.println("  mBooting=" + mBooting
13112                        + " mCallFinishBooting=" + mCallFinishBooting
13113                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13114                pw.print("  mLastPowerCheckRealtime=");
13115                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13116                        pw.println("");
13117                pw.print("  mLastPowerCheckUptime=");
13118                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13119                        pw.println("");
13120                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13121                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13122                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13123                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13124                        + " (" + mLruProcesses.size() + " total)"
13125                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13126                        + " mNumServiceProcs=" + mNumServiceProcs
13127                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13128                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13129                        + " mLastMemoryLevel" + mLastMemoryLevel
13130                        + " mLastNumProcesses" + mLastNumProcesses);
13131                long now = SystemClock.uptimeMillis();
13132                pw.print("  mLastIdleTime=");
13133                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13134                        pw.print(" mLowRamSinceLastIdle=");
13135                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13136                        pw.println();
13137            }
13138        }
13139
13140        if (!printedAnything) {
13141            pw.println("  (nothing)");
13142        }
13143    }
13144
13145    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13146            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13147        if (mProcessesToGc.size() > 0) {
13148            boolean printed = false;
13149            long now = SystemClock.uptimeMillis();
13150            for (int i=0; i<mProcessesToGc.size(); i++) {
13151                ProcessRecord proc = mProcessesToGc.get(i);
13152                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13153                    continue;
13154                }
13155                if (!printed) {
13156                    if (needSep) pw.println();
13157                    needSep = true;
13158                    pw.println("  Processes that are waiting to GC:");
13159                    printed = true;
13160                }
13161                pw.print("    Process "); pw.println(proc);
13162                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13163                        pw.print(", last gced=");
13164                        pw.print(now-proc.lastRequestedGc);
13165                        pw.print(" ms ago, last lowMem=");
13166                        pw.print(now-proc.lastLowMemory);
13167                        pw.println(" ms ago");
13168
13169            }
13170        }
13171        return needSep;
13172    }
13173
13174    void printOomLevel(PrintWriter pw, String name, int adj) {
13175        pw.print("    ");
13176        if (adj >= 0) {
13177            pw.print(' ');
13178            if (adj < 10) pw.print(' ');
13179        } else {
13180            if (adj > -10) pw.print(' ');
13181        }
13182        pw.print(adj);
13183        pw.print(": ");
13184        pw.print(name);
13185        pw.print(" (");
13186        pw.print(mProcessList.getMemLevel(adj)/1024);
13187        pw.println(" kB)");
13188    }
13189
13190    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13191            int opti, boolean dumpAll) {
13192        boolean needSep = false;
13193
13194        if (mLruProcesses.size() > 0) {
13195            if (needSep) pw.println();
13196            needSep = true;
13197            pw.println("  OOM levels:");
13198            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13199            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13200            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13201            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13202            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13203            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13204            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13205            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13206            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13207            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13208            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13209            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13210            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13211            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13212
13213            if (needSep) pw.println();
13214            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13215                    pw.print(" total, non-act at ");
13216                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13217                    pw.print(", non-svc at ");
13218                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13219                    pw.println("):");
13220            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13221            needSep = true;
13222        }
13223
13224        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13225
13226        pw.println();
13227        pw.println("  mHomeProcess: " + mHomeProcess);
13228        pw.println("  mPreviousProcess: " + mPreviousProcess);
13229        if (mHeavyWeightProcess != null) {
13230            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13231        }
13232
13233        return true;
13234    }
13235
13236    /**
13237     * There are three ways to call this:
13238     *  - no provider specified: dump all the providers
13239     *  - a flattened component name that matched an existing provider was specified as the
13240     *    first arg: dump that one provider
13241     *  - the first arg isn't the flattened component name of an existing provider:
13242     *    dump all providers whose component contains the first arg as a substring
13243     */
13244    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13245            int opti, boolean dumpAll) {
13246        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13247    }
13248
13249    static class ItemMatcher {
13250        ArrayList<ComponentName> components;
13251        ArrayList<String> strings;
13252        ArrayList<Integer> objects;
13253        boolean all;
13254
13255        ItemMatcher() {
13256            all = true;
13257        }
13258
13259        void build(String name) {
13260            ComponentName componentName = ComponentName.unflattenFromString(name);
13261            if (componentName != null) {
13262                if (components == null) {
13263                    components = new ArrayList<ComponentName>();
13264                }
13265                components.add(componentName);
13266                all = false;
13267            } else {
13268                int objectId = 0;
13269                // Not a '/' separated full component name; maybe an object ID?
13270                try {
13271                    objectId = Integer.parseInt(name, 16);
13272                    if (objects == null) {
13273                        objects = new ArrayList<Integer>();
13274                    }
13275                    objects.add(objectId);
13276                    all = false;
13277                } catch (RuntimeException e) {
13278                    // Not an integer; just do string match.
13279                    if (strings == null) {
13280                        strings = new ArrayList<String>();
13281                    }
13282                    strings.add(name);
13283                    all = false;
13284                }
13285            }
13286        }
13287
13288        int build(String[] args, int opti) {
13289            for (; opti<args.length; opti++) {
13290                String name = args[opti];
13291                if ("--".equals(name)) {
13292                    return opti+1;
13293                }
13294                build(name);
13295            }
13296            return opti;
13297        }
13298
13299        boolean match(Object object, ComponentName comp) {
13300            if (all) {
13301                return true;
13302            }
13303            if (components != null) {
13304                for (int i=0; i<components.size(); i++) {
13305                    if (components.get(i).equals(comp)) {
13306                        return true;
13307                    }
13308                }
13309            }
13310            if (objects != null) {
13311                for (int i=0; i<objects.size(); i++) {
13312                    if (System.identityHashCode(object) == objects.get(i)) {
13313                        return true;
13314                    }
13315                }
13316            }
13317            if (strings != null) {
13318                String flat = comp.flattenToString();
13319                for (int i=0; i<strings.size(); i++) {
13320                    if (flat.contains(strings.get(i))) {
13321                        return true;
13322                    }
13323                }
13324            }
13325            return false;
13326        }
13327    }
13328
13329    /**
13330     * There are three things that cmd can be:
13331     *  - a flattened component name that matches an existing activity
13332     *  - the cmd arg isn't the flattened component name of an existing activity:
13333     *    dump all activity whose component contains the cmd as a substring
13334     *  - A hex number of the ActivityRecord object instance.
13335     */
13336    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13337            int opti, boolean dumpAll) {
13338        ArrayList<ActivityRecord> activities;
13339
13340        synchronized (this) {
13341            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13342        }
13343
13344        if (activities.size() <= 0) {
13345            return false;
13346        }
13347
13348        String[] newArgs = new String[args.length - opti];
13349        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13350
13351        TaskRecord lastTask = null;
13352        boolean needSep = false;
13353        for (int i=activities.size()-1; i>=0; i--) {
13354            ActivityRecord r = activities.get(i);
13355            if (needSep) {
13356                pw.println();
13357            }
13358            needSep = true;
13359            synchronized (this) {
13360                if (lastTask != r.task) {
13361                    lastTask = r.task;
13362                    pw.print("TASK "); pw.print(lastTask.affinity);
13363                            pw.print(" id="); pw.println(lastTask.taskId);
13364                    if (dumpAll) {
13365                        lastTask.dump(pw, "  ");
13366                    }
13367                }
13368            }
13369            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13370        }
13371        return true;
13372    }
13373
13374    /**
13375     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13376     * there is a thread associated with the activity.
13377     */
13378    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13379            final ActivityRecord r, String[] args, boolean dumpAll) {
13380        String innerPrefix = prefix + "  ";
13381        synchronized (this) {
13382            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13383                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13384                    pw.print(" pid=");
13385                    if (r.app != null) pw.println(r.app.pid);
13386                    else pw.println("(not running)");
13387            if (dumpAll) {
13388                r.dump(pw, innerPrefix);
13389            }
13390        }
13391        if (r.app != null && r.app.thread != null) {
13392            // flush anything that is already in the PrintWriter since the thread is going
13393            // to write to the file descriptor directly
13394            pw.flush();
13395            try {
13396                TransferPipe tp = new TransferPipe();
13397                try {
13398                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13399                            r.appToken, innerPrefix, args);
13400                    tp.go(fd);
13401                } finally {
13402                    tp.kill();
13403                }
13404            } catch (IOException e) {
13405                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13406            } catch (RemoteException e) {
13407                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13408            }
13409        }
13410    }
13411
13412    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13413            int opti, boolean dumpAll, String dumpPackage) {
13414        boolean needSep = false;
13415        boolean onlyHistory = false;
13416        boolean printedAnything = false;
13417
13418        if ("history".equals(dumpPackage)) {
13419            if (opti < args.length && "-s".equals(args[opti])) {
13420                dumpAll = false;
13421            }
13422            onlyHistory = true;
13423            dumpPackage = null;
13424        }
13425
13426        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13427        if (!onlyHistory && dumpAll) {
13428            if (mRegisteredReceivers.size() > 0) {
13429                boolean printed = false;
13430                Iterator it = mRegisteredReceivers.values().iterator();
13431                while (it.hasNext()) {
13432                    ReceiverList r = (ReceiverList)it.next();
13433                    if (dumpPackage != null && (r.app == null ||
13434                            !dumpPackage.equals(r.app.info.packageName))) {
13435                        continue;
13436                    }
13437                    if (!printed) {
13438                        pw.println("  Registered Receivers:");
13439                        needSep = true;
13440                        printed = true;
13441                        printedAnything = true;
13442                    }
13443                    pw.print("  * "); pw.println(r);
13444                    r.dump(pw, "    ");
13445                }
13446            }
13447
13448            if (mReceiverResolver.dump(pw, needSep ?
13449                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13450                    "    ", dumpPackage, false, false)) {
13451                needSep = true;
13452                printedAnything = true;
13453            }
13454        }
13455
13456        for (BroadcastQueue q : mBroadcastQueues) {
13457            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13458            printedAnything |= needSep;
13459        }
13460
13461        needSep = true;
13462
13463        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13464            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13465                if (needSep) {
13466                    pw.println();
13467                }
13468                needSep = true;
13469                printedAnything = true;
13470                pw.print("  Sticky broadcasts for user ");
13471                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13472                StringBuilder sb = new StringBuilder(128);
13473                for (Map.Entry<String, ArrayList<Intent>> ent
13474                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13475                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13476                    if (dumpAll) {
13477                        pw.println(":");
13478                        ArrayList<Intent> intents = ent.getValue();
13479                        final int N = intents.size();
13480                        for (int i=0; i<N; i++) {
13481                            sb.setLength(0);
13482                            sb.append("    Intent: ");
13483                            intents.get(i).toShortString(sb, false, true, false, false);
13484                            pw.println(sb.toString());
13485                            Bundle bundle = intents.get(i).getExtras();
13486                            if (bundle != null) {
13487                                pw.print("      ");
13488                                pw.println(bundle.toString());
13489                            }
13490                        }
13491                    } else {
13492                        pw.println("");
13493                    }
13494                }
13495            }
13496        }
13497
13498        if (!onlyHistory && dumpAll) {
13499            pw.println();
13500            for (BroadcastQueue queue : mBroadcastQueues) {
13501                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13502                        + queue.mBroadcastsScheduled);
13503            }
13504            pw.println("  mHandler:");
13505            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13506            needSep = true;
13507            printedAnything = true;
13508        }
13509
13510        if (!printedAnything) {
13511            pw.println("  (nothing)");
13512        }
13513    }
13514
13515    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13516            int opti, boolean dumpAll, String dumpPackage) {
13517        boolean needSep;
13518        boolean printedAnything = false;
13519
13520        ItemMatcher matcher = new ItemMatcher();
13521        matcher.build(args, opti);
13522
13523        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13524
13525        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13526        printedAnything |= needSep;
13527
13528        if (mLaunchingProviders.size() > 0) {
13529            boolean printed = false;
13530            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13531                ContentProviderRecord r = mLaunchingProviders.get(i);
13532                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13533                    continue;
13534                }
13535                if (!printed) {
13536                    if (needSep) pw.println();
13537                    needSep = true;
13538                    pw.println("  Launching content providers:");
13539                    printed = true;
13540                    printedAnything = true;
13541                }
13542                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13543                        pw.println(r);
13544            }
13545        }
13546
13547        if (mGrantedUriPermissions.size() > 0) {
13548            boolean printed = false;
13549            int dumpUid = -2;
13550            if (dumpPackage != null) {
13551                try {
13552                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13553                } catch (NameNotFoundException e) {
13554                    dumpUid = -1;
13555                }
13556            }
13557            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13558                int uid = mGrantedUriPermissions.keyAt(i);
13559                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13560                    continue;
13561                }
13562                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13563                if (!printed) {
13564                    if (needSep) pw.println();
13565                    needSep = true;
13566                    pw.println("  Granted Uri Permissions:");
13567                    printed = true;
13568                    printedAnything = true;
13569                }
13570                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13571                for (UriPermission perm : perms.values()) {
13572                    pw.print("    "); pw.println(perm);
13573                    if (dumpAll) {
13574                        perm.dump(pw, "      ");
13575                    }
13576                }
13577            }
13578        }
13579
13580        if (!printedAnything) {
13581            pw.println("  (nothing)");
13582        }
13583    }
13584
13585    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13586            int opti, boolean dumpAll, String dumpPackage) {
13587        boolean printed = false;
13588
13589        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13590
13591        if (mIntentSenderRecords.size() > 0) {
13592            Iterator<WeakReference<PendingIntentRecord>> it
13593                    = mIntentSenderRecords.values().iterator();
13594            while (it.hasNext()) {
13595                WeakReference<PendingIntentRecord> ref = it.next();
13596                PendingIntentRecord rec = ref != null ? ref.get(): null;
13597                if (dumpPackage != null && (rec == null
13598                        || !dumpPackage.equals(rec.key.packageName))) {
13599                    continue;
13600                }
13601                printed = true;
13602                if (rec != null) {
13603                    pw.print("  * "); pw.println(rec);
13604                    if (dumpAll) {
13605                        rec.dump(pw, "    ");
13606                    }
13607                } else {
13608                    pw.print("  * "); pw.println(ref);
13609                }
13610            }
13611        }
13612
13613        if (!printed) {
13614            pw.println("  (nothing)");
13615        }
13616    }
13617
13618    private static final int dumpProcessList(PrintWriter pw,
13619            ActivityManagerService service, List list,
13620            String prefix, String normalLabel, String persistentLabel,
13621            String dumpPackage) {
13622        int numPers = 0;
13623        final int N = list.size()-1;
13624        for (int i=N; i>=0; i--) {
13625            ProcessRecord r = (ProcessRecord)list.get(i);
13626            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13627                continue;
13628            }
13629            pw.println(String.format("%s%s #%2d: %s",
13630                    prefix, (r.persistent ? persistentLabel : normalLabel),
13631                    i, r.toString()));
13632            if (r.persistent) {
13633                numPers++;
13634            }
13635        }
13636        return numPers;
13637    }
13638
13639    private static final boolean dumpProcessOomList(PrintWriter pw,
13640            ActivityManagerService service, List<ProcessRecord> origList,
13641            String prefix, String normalLabel, String persistentLabel,
13642            boolean inclDetails, String dumpPackage) {
13643
13644        ArrayList<Pair<ProcessRecord, Integer>> list
13645                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13646        for (int i=0; i<origList.size(); i++) {
13647            ProcessRecord r = origList.get(i);
13648            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13649                continue;
13650            }
13651            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13652        }
13653
13654        if (list.size() <= 0) {
13655            return false;
13656        }
13657
13658        Comparator<Pair<ProcessRecord, Integer>> comparator
13659                = new Comparator<Pair<ProcessRecord, Integer>>() {
13660            @Override
13661            public int compare(Pair<ProcessRecord, Integer> object1,
13662                    Pair<ProcessRecord, Integer> object2) {
13663                if (object1.first.setAdj != object2.first.setAdj) {
13664                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13665                }
13666                if (object1.second.intValue() != object2.second.intValue()) {
13667                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13668                }
13669                return 0;
13670            }
13671        };
13672
13673        Collections.sort(list, comparator);
13674
13675        final long curRealtime = SystemClock.elapsedRealtime();
13676        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13677        final long curUptime = SystemClock.uptimeMillis();
13678        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13679
13680        for (int i=list.size()-1; i>=0; i--) {
13681            ProcessRecord r = list.get(i).first;
13682            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13683            char schedGroup;
13684            switch (r.setSchedGroup) {
13685                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13686                    schedGroup = 'B';
13687                    break;
13688                case Process.THREAD_GROUP_DEFAULT:
13689                    schedGroup = 'F';
13690                    break;
13691                default:
13692                    schedGroup = '?';
13693                    break;
13694            }
13695            char foreground;
13696            if (r.foregroundActivities) {
13697                foreground = 'A';
13698            } else if (r.foregroundServices) {
13699                foreground = 'S';
13700            } else {
13701                foreground = ' ';
13702            }
13703            String procState = ProcessList.makeProcStateString(r.curProcState);
13704            pw.print(prefix);
13705            pw.print(r.persistent ? persistentLabel : normalLabel);
13706            pw.print(" #");
13707            int num = (origList.size()-1)-list.get(i).second;
13708            if (num < 10) pw.print(' ');
13709            pw.print(num);
13710            pw.print(": ");
13711            pw.print(oomAdj);
13712            pw.print(' ');
13713            pw.print(schedGroup);
13714            pw.print('/');
13715            pw.print(foreground);
13716            pw.print('/');
13717            pw.print(procState);
13718            pw.print(" trm:");
13719            if (r.trimMemoryLevel < 10) pw.print(' ');
13720            pw.print(r.trimMemoryLevel);
13721            pw.print(' ');
13722            pw.print(r.toShortString());
13723            pw.print(" (");
13724            pw.print(r.adjType);
13725            pw.println(')');
13726            if (r.adjSource != null || r.adjTarget != null) {
13727                pw.print(prefix);
13728                pw.print("    ");
13729                if (r.adjTarget instanceof ComponentName) {
13730                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13731                } else if (r.adjTarget != null) {
13732                    pw.print(r.adjTarget.toString());
13733                } else {
13734                    pw.print("{null}");
13735                }
13736                pw.print("<=");
13737                if (r.adjSource instanceof ProcessRecord) {
13738                    pw.print("Proc{");
13739                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13740                    pw.println("}");
13741                } else if (r.adjSource != null) {
13742                    pw.println(r.adjSource.toString());
13743                } else {
13744                    pw.println("{null}");
13745                }
13746            }
13747            if (inclDetails) {
13748                pw.print(prefix);
13749                pw.print("    ");
13750                pw.print("oom: max="); pw.print(r.maxAdj);
13751                pw.print(" curRaw="); pw.print(r.curRawAdj);
13752                pw.print(" setRaw="); pw.print(r.setRawAdj);
13753                pw.print(" cur="); pw.print(r.curAdj);
13754                pw.print(" set="); pw.println(r.setAdj);
13755                pw.print(prefix);
13756                pw.print("    ");
13757                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13758                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13759                pw.print(" lastPss="); pw.print(r.lastPss);
13760                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13761                pw.print(prefix);
13762                pw.print("    ");
13763                pw.print("cached="); pw.print(r.cached);
13764                pw.print(" empty="); pw.print(r.empty);
13765                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13766
13767                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13768                    if (r.lastWakeTime != 0) {
13769                        long wtime;
13770                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13771                        synchronized (stats) {
13772                            wtime = stats.getProcessWakeTime(r.info.uid,
13773                                    r.pid, curRealtime);
13774                        }
13775                        long timeUsed = wtime - r.lastWakeTime;
13776                        pw.print(prefix);
13777                        pw.print("    ");
13778                        pw.print("keep awake over ");
13779                        TimeUtils.formatDuration(realtimeSince, pw);
13780                        pw.print(" used ");
13781                        TimeUtils.formatDuration(timeUsed, pw);
13782                        pw.print(" (");
13783                        pw.print((timeUsed*100)/realtimeSince);
13784                        pw.println("%)");
13785                    }
13786                    if (r.lastCpuTime != 0) {
13787                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13788                        pw.print(prefix);
13789                        pw.print("    ");
13790                        pw.print("run cpu over ");
13791                        TimeUtils.formatDuration(uptimeSince, pw);
13792                        pw.print(" used ");
13793                        TimeUtils.formatDuration(timeUsed, pw);
13794                        pw.print(" (");
13795                        pw.print((timeUsed*100)/uptimeSince);
13796                        pw.println("%)");
13797                    }
13798                }
13799            }
13800        }
13801        return true;
13802    }
13803
13804    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13805            String[] args) {
13806        ArrayList<ProcessRecord> procs;
13807        synchronized (this) {
13808            if (args != null && args.length > start
13809                    && args[start].charAt(0) != '-') {
13810                procs = new ArrayList<ProcessRecord>();
13811                int pid = -1;
13812                try {
13813                    pid = Integer.parseInt(args[start]);
13814                } catch (NumberFormatException e) {
13815                }
13816                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13817                    ProcessRecord proc = mLruProcesses.get(i);
13818                    if (proc.pid == pid) {
13819                        procs.add(proc);
13820                    } else if (allPkgs && proc.pkgList != null
13821                            && proc.pkgList.containsKey(args[start])) {
13822                        procs.add(proc);
13823                    } else if (proc.processName.equals(args[start])) {
13824                        procs.add(proc);
13825                    }
13826                }
13827                if (procs.size() <= 0) {
13828                    return null;
13829                }
13830            } else {
13831                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13832            }
13833        }
13834        return procs;
13835    }
13836
13837    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13838            PrintWriter pw, String[] args) {
13839        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13840        if (procs == null) {
13841            pw.println("No process found for: " + args[0]);
13842            return;
13843        }
13844
13845        long uptime = SystemClock.uptimeMillis();
13846        long realtime = SystemClock.elapsedRealtime();
13847        pw.println("Applications Graphics Acceleration Info:");
13848        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13849
13850        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13851            ProcessRecord r = procs.get(i);
13852            if (r.thread != null) {
13853                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13854                pw.flush();
13855                try {
13856                    TransferPipe tp = new TransferPipe();
13857                    try {
13858                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13859                        tp.go(fd);
13860                    } finally {
13861                        tp.kill();
13862                    }
13863                } catch (IOException e) {
13864                    pw.println("Failure while dumping the app: " + r);
13865                    pw.flush();
13866                } catch (RemoteException e) {
13867                    pw.println("Got a RemoteException while dumping the app " + r);
13868                    pw.flush();
13869                }
13870            }
13871        }
13872    }
13873
13874    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13875        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13876        if (procs == null) {
13877            pw.println("No process found for: " + args[0]);
13878            return;
13879        }
13880
13881        pw.println("Applications Database Info:");
13882
13883        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13884            ProcessRecord r = procs.get(i);
13885            if (r.thread != null) {
13886                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13887                pw.flush();
13888                try {
13889                    TransferPipe tp = new TransferPipe();
13890                    try {
13891                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13892                        tp.go(fd);
13893                    } finally {
13894                        tp.kill();
13895                    }
13896                } catch (IOException e) {
13897                    pw.println("Failure while dumping the app: " + r);
13898                    pw.flush();
13899                } catch (RemoteException e) {
13900                    pw.println("Got a RemoteException while dumping the app " + r);
13901                    pw.flush();
13902                }
13903            }
13904        }
13905    }
13906
13907    final static class MemItem {
13908        final boolean isProc;
13909        final String label;
13910        final String shortLabel;
13911        final long pss;
13912        final int id;
13913        final boolean hasActivities;
13914        ArrayList<MemItem> subitems;
13915
13916        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13917                boolean _hasActivities) {
13918            isProc = true;
13919            label = _label;
13920            shortLabel = _shortLabel;
13921            pss = _pss;
13922            id = _id;
13923            hasActivities = _hasActivities;
13924        }
13925
13926        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13927            isProc = false;
13928            label = _label;
13929            shortLabel = _shortLabel;
13930            pss = _pss;
13931            id = _id;
13932            hasActivities = false;
13933        }
13934    }
13935
13936    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13937            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13938        if (sort && !isCompact) {
13939            Collections.sort(items, new Comparator<MemItem>() {
13940                @Override
13941                public int compare(MemItem lhs, MemItem rhs) {
13942                    if (lhs.pss < rhs.pss) {
13943                        return 1;
13944                    } else if (lhs.pss > rhs.pss) {
13945                        return -1;
13946                    }
13947                    return 0;
13948                }
13949            });
13950        }
13951
13952        for (int i=0; i<items.size(); i++) {
13953            MemItem mi = items.get(i);
13954            if (!isCompact) {
13955                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13956            } else if (mi.isProc) {
13957                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13958                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13959                pw.println(mi.hasActivities ? ",a" : ",e");
13960            } else {
13961                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13962                pw.println(mi.pss);
13963            }
13964            if (mi.subitems != null) {
13965                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13966                        true, isCompact);
13967            }
13968        }
13969    }
13970
13971    // These are in KB.
13972    static final long[] DUMP_MEM_BUCKETS = new long[] {
13973        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13974        120*1024, 160*1024, 200*1024,
13975        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13976        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13977    };
13978
13979    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13980            boolean stackLike) {
13981        int start = label.lastIndexOf('.');
13982        if (start >= 0) start++;
13983        else start = 0;
13984        int end = label.length();
13985        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13986            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13987                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13988                out.append(bucket);
13989                out.append(stackLike ? "MB." : "MB ");
13990                out.append(label, start, end);
13991                return;
13992            }
13993        }
13994        out.append(memKB/1024);
13995        out.append(stackLike ? "MB." : "MB ");
13996        out.append(label, start, end);
13997    }
13998
13999    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14000            ProcessList.NATIVE_ADJ,
14001            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14002            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14003            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14004            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14005            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14006            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14007    };
14008    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14009            "Native",
14010            "System", "Persistent", "Persistent Service", "Foreground",
14011            "Visible", "Perceptible",
14012            "Heavy Weight", "Backup",
14013            "A Services", "Home",
14014            "Previous", "B Services", "Cached"
14015    };
14016    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14017            "native",
14018            "sys", "pers", "persvc", "fore",
14019            "vis", "percept",
14020            "heavy", "backup",
14021            "servicea", "home",
14022            "prev", "serviceb", "cached"
14023    };
14024
14025    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14026            long realtime, boolean isCheckinRequest, boolean isCompact) {
14027        if (isCheckinRequest || isCompact) {
14028            // short checkin version
14029            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14030        } else {
14031            pw.println("Applications Memory Usage (kB):");
14032            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14033        }
14034    }
14035
14036    private static final int KSM_SHARED = 0;
14037    private static final int KSM_SHARING = 1;
14038    private static final int KSM_UNSHARED = 2;
14039    private static final int KSM_VOLATILE = 3;
14040
14041    private final long[] getKsmInfo() {
14042        long[] longOut = new long[4];
14043        final int[] SINGLE_LONG_FORMAT = new int[] {
14044            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14045        };
14046        long[] longTmp = new long[1];
14047        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14048                SINGLE_LONG_FORMAT, null, longTmp, null);
14049        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14050        longTmp[0] = 0;
14051        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14052                SINGLE_LONG_FORMAT, null, longTmp, null);
14053        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14054        longTmp[0] = 0;
14055        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14056                SINGLE_LONG_FORMAT, null, longTmp, null);
14057        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14058        longTmp[0] = 0;
14059        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14060                SINGLE_LONG_FORMAT, null, longTmp, null);
14061        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14062        return longOut;
14063    }
14064
14065    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14066            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14067        boolean dumpDetails = false;
14068        boolean dumpFullDetails = false;
14069        boolean dumpDalvik = false;
14070        boolean oomOnly = false;
14071        boolean isCompact = false;
14072        boolean localOnly = false;
14073        boolean packages = false;
14074
14075        int opti = 0;
14076        while (opti < args.length) {
14077            String opt = args[opti];
14078            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14079                break;
14080            }
14081            opti++;
14082            if ("-a".equals(opt)) {
14083                dumpDetails = true;
14084                dumpFullDetails = true;
14085                dumpDalvik = true;
14086            } else if ("-d".equals(opt)) {
14087                dumpDalvik = true;
14088            } else if ("-c".equals(opt)) {
14089                isCompact = true;
14090            } else if ("--oom".equals(opt)) {
14091                oomOnly = true;
14092            } else if ("--local".equals(opt)) {
14093                localOnly = true;
14094            } else if ("--package".equals(opt)) {
14095                packages = true;
14096            } else if ("-h".equals(opt)) {
14097                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14098                pw.println("  -a: include all available information for each process.");
14099                pw.println("  -d: include dalvik details when dumping process details.");
14100                pw.println("  -c: dump in a compact machine-parseable representation.");
14101                pw.println("  --oom: only show processes organized by oom adj.");
14102                pw.println("  --local: only collect details locally, don't call process.");
14103                pw.println("  --package: interpret process arg as package, dumping all");
14104                pw.println("             processes that have loaded that package.");
14105                pw.println("If [process] is specified it can be the name or ");
14106                pw.println("pid of a specific process to dump.");
14107                return;
14108            } else {
14109                pw.println("Unknown argument: " + opt + "; use -h for help");
14110            }
14111        }
14112
14113        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14114        long uptime = SystemClock.uptimeMillis();
14115        long realtime = SystemClock.elapsedRealtime();
14116        final long[] tmpLong = new long[1];
14117
14118        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14119        if (procs == null) {
14120            // No Java processes.  Maybe they want to print a native process.
14121            if (args != null && args.length > opti
14122                    && args[opti].charAt(0) != '-') {
14123                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14124                        = new ArrayList<ProcessCpuTracker.Stats>();
14125                updateCpuStatsNow();
14126                int findPid = -1;
14127                try {
14128                    findPid = Integer.parseInt(args[opti]);
14129                } catch (NumberFormatException e) {
14130                }
14131                synchronized (mProcessCpuTracker) {
14132                    final int N = mProcessCpuTracker.countStats();
14133                    for (int i=0; i<N; i++) {
14134                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14135                        if (st.pid == findPid || (st.baseName != null
14136                                && st.baseName.equals(args[opti]))) {
14137                            nativeProcs.add(st);
14138                        }
14139                    }
14140                }
14141                if (nativeProcs.size() > 0) {
14142                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14143                            isCompact);
14144                    Debug.MemoryInfo mi = null;
14145                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14146                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14147                        final int pid = r.pid;
14148                        if (!isCheckinRequest && dumpDetails) {
14149                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14150                        }
14151                        if (mi == null) {
14152                            mi = new Debug.MemoryInfo();
14153                        }
14154                        if (dumpDetails || (!brief && !oomOnly)) {
14155                            Debug.getMemoryInfo(pid, mi);
14156                        } else {
14157                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14158                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14159                        }
14160                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14161                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14162                        if (isCheckinRequest) {
14163                            pw.println();
14164                        }
14165                    }
14166                    return;
14167                }
14168            }
14169            pw.println("No process found for: " + args[opti]);
14170            return;
14171        }
14172
14173        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14174            dumpDetails = true;
14175        }
14176
14177        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14178
14179        String[] innerArgs = new String[args.length-opti];
14180        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14181
14182        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14183        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14184        long nativePss = 0;
14185        long dalvikPss = 0;
14186        long otherPss = 0;
14187        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14188
14189        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14190        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14191                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14192
14193        long totalPss = 0;
14194        long cachedPss = 0;
14195
14196        Debug.MemoryInfo mi = null;
14197        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14198            final ProcessRecord r = procs.get(i);
14199            final IApplicationThread thread;
14200            final int pid;
14201            final int oomAdj;
14202            final boolean hasActivities;
14203            synchronized (this) {
14204                thread = r.thread;
14205                pid = r.pid;
14206                oomAdj = r.getSetAdjWithServices();
14207                hasActivities = r.activities.size() > 0;
14208            }
14209            if (thread != null) {
14210                if (!isCheckinRequest && dumpDetails) {
14211                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14212                }
14213                if (mi == null) {
14214                    mi = new Debug.MemoryInfo();
14215                }
14216                if (dumpDetails || (!brief && !oomOnly)) {
14217                    Debug.getMemoryInfo(pid, mi);
14218                } else {
14219                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14220                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14221                }
14222                if (dumpDetails) {
14223                    if (localOnly) {
14224                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14225                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14226                        if (isCheckinRequest) {
14227                            pw.println();
14228                        }
14229                    } else {
14230                        try {
14231                            pw.flush();
14232                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14233                                    dumpDalvik, innerArgs);
14234                        } catch (RemoteException e) {
14235                            if (!isCheckinRequest) {
14236                                pw.println("Got RemoteException!");
14237                                pw.flush();
14238                            }
14239                        }
14240                    }
14241                }
14242
14243                final long myTotalPss = mi.getTotalPss();
14244                final long myTotalUss = mi.getTotalUss();
14245
14246                synchronized (this) {
14247                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14248                        // Record this for posterity if the process has been stable.
14249                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14250                    }
14251                }
14252
14253                if (!isCheckinRequest && mi != null) {
14254                    totalPss += myTotalPss;
14255                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14256                            (hasActivities ? " / activities)" : ")"),
14257                            r.processName, myTotalPss, pid, hasActivities);
14258                    procMems.add(pssItem);
14259                    procMemsMap.put(pid, pssItem);
14260
14261                    nativePss += mi.nativePss;
14262                    dalvikPss += mi.dalvikPss;
14263                    otherPss += mi.otherPss;
14264                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14265                        long mem = mi.getOtherPss(j);
14266                        miscPss[j] += mem;
14267                        otherPss -= mem;
14268                    }
14269
14270                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14271                        cachedPss += myTotalPss;
14272                    }
14273
14274                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14275                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14276                                || oomIndex == (oomPss.length-1)) {
14277                            oomPss[oomIndex] += myTotalPss;
14278                            if (oomProcs[oomIndex] == null) {
14279                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14280                            }
14281                            oomProcs[oomIndex].add(pssItem);
14282                            break;
14283                        }
14284                    }
14285                }
14286            }
14287        }
14288
14289        long nativeProcTotalPss = 0;
14290
14291        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14292            // If we are showing aggregations, also look for native processes to
14293            // include so that our aggregations are more accurate.
14294            updateCpuStatsNow();
14295            mi = null;
14296            synchronized (mProcessCpuTracker) {
14297                final int N = mProcessCpuTracker.countStats();
14298                for (int i=0; i<N; i++) {
14299                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14300                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14301                        if (mi == null) {
14302                            mi = new Debug.MemoryInfo();
14303                        }
14304                        if (!brief && !oomOnly) {
14305                            Debug.getMemoryInfo(st.pid, mi);
14306                        } else {
14307                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14308                            mi.nativePrivateDirty = (int)tmpLong[0];
14309                        }
14310
14311                        final long myTotalPss = mi.getTotalPss();
14312                        totalPss += myTotalPss;
14313                        nativeProcTotalPss += myTotalPss;
14314
14315                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14316                                st.name, myTotalPss, st.pid, false);
14317                        procMems.add(pssItem);
14318
14319                        nativePss += mi.nativePss;
14320                        dalvikPss += mi.dalvikPss;
14321                        otherPss += mi.otherPss;
14322                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14323                            long mem = mi.getOtherPss(j);
14324                            miscPss[j] += mem;
14325                            otherPss -= mem;
14326                        }
14327                        oomPss[0] += myTotalPss;
14328                        if (oomProcs[0] == null) {
14329                            oomProcs[0] = new ArrayList<MemItem>();
14330                        }
14331                        oomProcs[0].add(pssItem);
14332                    }
14333                }
14334            }
14335
14336            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14337
14338            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14339            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14340            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14341            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14342                String label = Debug.MemoryInfo.getOtherLabel(j);
14343                catMems.add(new MemItem(label, label, miscPss[j], j));
14344            }
14345
14346            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14347            for (int j=0; j<oomPss.length; j++) {
14348                if (oomPss[j] != 0) {
14349                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14350                            : DUMP_MEM_OOM_LABEL[j];
14351                    MemItem item = new MemItem(label, label, oomPss[j],
14352                            DUMP_MEM_OOM_ADJ[j]);
14353                    item.subitems = oomProcs[j];
14354                    oomMems.add(item);
14355                }
14356            }
14357
14358            if (!brief && !oomOnly && !isCompact) {
14359                pw.println();
14360                pw.println("Total PSS by process:");
14361                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14362                pw.println();
14363            }
14364            if (!isCompact) {
14365                pw.println("Total PSS by OOM adjustment:");
14366            }
14367            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14368            if (!brief && !oomOnly) {
14369                PrintWriter out = categoryPw != null ? categoryPw : pw;
14370                if (!isCompact) {
14371                    out.println();
14372                    out.println("Total PSS by category:");
14373                }
14374                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14375            }
14376            if (!isCompact) {
14377                pw.println();
14378            }
14379            MemInfoReader memInfo = new MemInfoReader();
14380            memInfo.readMemInfo();
14381            if (nativeProcTotalPss > 0) {
14382                synchronized (this) {
14383                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14384                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14385                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14386                }
14387            }
14388            if (!brief) {
14389                if (!isCompact) {
14390                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14391                    pw.print(" kB (status ");
14392                    switch (mLastMemoryLevel) {
14393                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14394                            pw.println("normal)");
14395                            break;
14396                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14397                            pw.println("moderate)");
14398                            break;
14399                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14400                            pw.println("low)");
14401                            break;
14402                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14403                            pw.println("critical)");
14404                            break;
14405                        default:
14406                            pw.print(mLastMemoryLevel);
14407                            pw.println(")");
14408                            break;
14409                    }
14410                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14411                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14412                            pw.print(cachedPss); pw.print(" cached pss + ");
14413                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14414                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14415                } else {
14416                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14417                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14418                            + memInfo.getFreeSizeKb()); pw.print(",");
14419                    pw.println(totalPss - cachedPss);
14420                }
14421            }
14422            if (!isCompact) {
14423                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14424                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14425                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14426                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14427                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14428                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14429                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14430            }
14431            if (!brief) {
14432                if (memInfo.getZramTotalSizeKb() != 0) {
14433                    if (!isCompact) {
14434                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14435                                pw.print(" kB physical used for ");
14436                                pw.print(memInfo.getSwapTotalSizeKb()
14437                                        - memInfo.getSwapFreeSizeKb());
14438                                pw.print(" kB in swap (");
14439                                pw.print(memInfo.getSwapTotalSizeKb());
14440                                pw.println(" kB total swap)");
14441                    } else {
14442                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14443                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14444                                pw.println(memInfo.getSwapFreeSizeKb());
14445                    }
14446                }
14447                final long[] ksm = getKsmInfo();
14448                if (!isCompact) {
14449                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14450                            || ksm[KSM_VOLATILE] != 0) {
14451                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14452                                pw.print(" kB saved from shared ");
14453                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14454                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14455                                pw.print(" kB unshared; ");
14456                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14457                    }
14458                    pw.print("   Tuning: ");
14459                    pw.print(ActivityManager.staticGetMemoryClass());
14460                    pw.print(" (large ");
14461                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14462                    pw.print("), oom ");
14463                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14464                    pw.print(" kB");
14465                    pw.print(", restore limit ");
14466                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14467                    pw.print(" kB");
14468                    if (ActivityManager.isLowRamDeviceStatic()) {
14469                        pw.print(" (low-ram)");
14470                    }
14471                    if (ActivityManager.isHighEndGfx()) {
14472                        pw.print(" (high-end-gfx)");
14473                    }
14474                    pw.println();
14475                } else {
14476                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14477                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14478                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14479                    pw.print("tuning,");
14480                    pw.print(ActivityManager.staticGetMemoryClass());
14481                    pw.print(',');
14482                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14483                    pw.print(',');
14484                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14485                    if (ActivityManager.isLowRamDeviceStatic()) {
14486                        pw.print(",low-ram");
14487                    }
14488                    if (ActivityManager.isHighEndGfx()) {
14489                        pw.print(",high-end-gfx");
14490                    }
14491                    pw.println();
14492                }
14493            }
14494        }
14495    }
14496
14497    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14498            long memtrack, String name) {
14499        sb.append("  ");
14500        sb.append(ProcessList.makeOomAdjString(oomAdj));
14501        sb.append(' ');
14502        sb.append(ProcessList.makeProcStateString(procState));
14503        sb.append(' ');
14504        ProcessList.appendRamKb(sb, pss);
14505        sb.append(" kB: ");
14506        sb.append(name);
14507        if (memtrack > 0) {
14508            sb.append(" (");
14509            sb.append(memtrack);
14510            sb.append(" kB memtrack)");
14511        }
14512    }
14513
14514    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14515        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14516        sb.append(" (pid ");
14517        sb.append(mi.pid);
14518        sb.append(") ");
14519        sb.append(mi.adjType);
14520        sb.append('\n');
14521        if (mi.adjReason != null) {
14522            sb.append("                      ");
14523            sb.append(mi.adjReason);
14524            sb.append('\n');
14525        }
14526    }
14527
14528    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14529        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14530        for (int i=0, N=memInfos.size(); i<N; i++) {
14531            ProcessMemInfo mi = memInfos.get(i);
14532            infoMap.put(mi.pid, mi);
14533        }
14534        updateCpuStatsNow();
14535        long[] memtrackTmp = new long[1];
14536        synchronized (mProcessCpuTracker) {
14537            final int N = mProcessCpuTracker.countStats();
14538            for (int i=0; i<N; i++) {
14539                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14540                if (st.vsize > 0) {
14541                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14542                    if (pss > 0) {
14543                        if (infoMap.indexOfKey(st.pid) < 0) {
14544                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14545                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14546                            mi.pss = pss;
14547                            mi.memtrack = memtrackTmp[0];
14548                            memInfos.add(mi);
14549                        }
14550                    }
14551                }
14552            }
14553        }
14554
14555        long totalPss = 0;
14556        long totalMemtrack = 0;
14557        for (int i=0, N=memInfos.size(); i<N; i++) {
14558            ProcessMemInfo mi = memInfos.get(i);
14559            if (mi.pss == 0) {
14560                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14561                mi.memtrack = memtrackTmp[0];
14562            }
14563            totalPss += mi.pss;
14564            totalMemtrack += mi.memtrack;
14565        }
14566        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14567            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14568                if (lhs.oomAdj != rhs.oomAdj) {
14569                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14570                }
14571                if (lhs.pss != rhs.pss) {
14572                    return lhs.pss < rhs.pss ? 1 : -1;
14573                }
14574                return 0;
14575            }
14576        });
14577
14578        StringBuilder tag = new StringBuilder(128);
14579        StringBuilder stack = new StringBuilder(128);
14580        tag.append("Low on memory -- ");
14581        appendMemBucket(tag, totalPss, "total", false);
14582        appendMemBucket(stack, totalPss, "total", true);
14583
14584        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14585        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14586        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14587
14588        boolean firstLine = true;
14589        int lastOomAdj = Integer.MIN_VALUE;
14590        long extraNativeRam = 0;
14591        long extraNativeMemtrack = 0;
14592        long cachedPss = 0;
14593        for (int i=0, N=memInfos.size(); i<N; i++) {
14594            ProcessMemInfo mi = memInfos.get(i);
14595
14596            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14597                cachedPss += mi.pss;
14598            }
14599
14600            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14601                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14602                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14603                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14604                if (lastOomAdj != mi.oomAdj) {
14605                    lastOomAdj = mi.oomAdj;
14606                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14607                        tag.append(" / ");
14608                    }
14609                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14610                        if (firstLine) {
14611                            stack.append(":");
14612                            firstLine = false;
14613                        }
14614                        stack.append("\n\t at ");
14615                    } else {
14616                        stack.append("$");
14617                    }
14618                } else {
14619                    tag.append(" ");
14620                    stack.append("$");
14621                }
14622                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14623                    appendMemBucket(tag, mi.pss, mi.name, false);
14624                }
14625                appendMemBucket(stack, mi.pss, mi.name, true);
14626                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14627                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14628                    stack.append("(");
14629                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14630                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14631                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14632                            stack.append(":");
14633                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14634                        }
14635                    }
14636                    stack.append(")");
14637                }
14638            }
14639
14640            appendMemInfo(fullNativeBuilder, mi);
14641            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14642                // The short form only has native processes that are >= 512K.
14643                if (mi.pss >= 512) {
14644                    appendMemInfo(shortNativeBuilder, mi);
14645                } else {
14646                    extraNativeRam += mi.pss;
14647                    extraNativeMemtrack += mi.memtrack;
14648                }
14649            } else {
14650                // Short form has all other details, but if we have collected RAM
14651                // from smaller native processes let's dump a summary of that.
14652                if (extraNativeRam > 0) {
14653                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14654                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14655                    shortNativeBuilder.append('\n');
14656                    extraNativeRam = 0;
14657                }
14658                appendMemInfo(fullJavaBuilder, mi);
14659            }
14660        }
14661
14662        fullJavaBuilder.append("           ");
14663        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14664        fullJavaBuilder.append(" kB: TOTAL");
14665        if (totalMemtrack > 0) {
14666            fullJavaBuilder.append(" (");
14667            fullJavaBuilder.append(totalMemtrack);
14668            fullJavaBuilder.append(" kB memtrack)");
14669        } else {
14670        }
14671        fullJavaBuilder.append("\n");
14672
14673        MemInfoReader memInfo = new MemInfoReader();
14674        memInfo.readMemInfo();
14675        final long[] infos = memInfo.getRawInfo();
14676
14677        StringBuilder memInfoBuilder = new StringBuilder(1024);
14678        Debug.getMemInfo(infos);
14679        memInfoBuilder.append("  MemInfo: ");
14680        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14681        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14682        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14683        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14684        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14685        memInfoBuilder.append("           ");
14686        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14687        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14688        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14689        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14690        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14691            memInfoBuilder.append("  ZRAM: ");
14692            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14693            memInfoBuilder.append(" kB RAM, ");
14694            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14695            memInfoBuilder.append(" kB swap total, ");
14696            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14697            memInfoBuilder.append(" kB swap free\n");
14698        }
14699        final long[] ksm = getKsmInfo();
14700        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14701                || ksm[KSM_VOLATILE] != 0) {
14702            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14703            memInfoBuilder.append(" kB saved from shared ");
14704            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14705            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14706            memInfoBuilder.append(" kB unshared; ");
14707            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14708        }
14709        memInfoBuilder.append("  Free RAM: ");
14710        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14711                + memInfo.getFreeSizeKb());
14712        memInfoBuilder.append(" kB\n");
14713        memInfoBuilder.append("  Used RAM: ");
14714        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14715        memInfoBuilder.append(" kB\n");
14716        memInfoBuilder.append("  Lost RAM: ");
14717        memInfoBuilder.append(memInfo.getTotalSizeKb()
14718                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14719                - memInfo.getKernelUsedSizeKb());
14720        memInfoBuilder.append(" kB\n");
14721        Slog.i(TAG, "Low on memory:");
14722        Slog.i(TAG, shortNativeBuilder.toString());
14723        Slog.i(TAG, fullJavaBuilder.toString());
14724        Slog.i(TAG, memInfoBuilder.toString());
14725
14726        StringBuilder dropBuilder = new StringBuilder(1024);
14727        /*
14728        StringWriter oomSw = new StringWriter();
14729        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14730        StringWriter catSw = new StringWriter();
14731        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14732        String[] emptyArgs = new String[] { };
14733        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14734        oomPw.flush();
14735        String oomString = oomSw.toString();
14736        */
14737        dropBuilder.append("Low on memory:");
14738        dropBuilder.append(stack);
14739        dropBuilder.append('\n');
14740        dropBuilder.append(fullNativeBuilder);
14741        dropBuilder.append(fullJavaBuilder);
14742        dropBuilder.append('\n');
14743        dropBuilder.append(memInfoBuilder);
14744        dropBuilder.append('\n');
14745        /*
14746        dropBuilder.append(oomString);
14747        dropBuilder.append('\n');
14748        */
14749        StringWriter catSw = new StringWriter();
14750        synchronized (ActivityManagerService.this) {
14751            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14752            String[] emptyArgs = new String[] { };
14753            catPw.println();
14754            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14755            catPw.println();
14756            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14757                    false, false, null);
14758            catPw.println();
14759            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14760            catPw.flush();
14761        }
14762        dropBuilder.append(catSw.toString());
14763        addErrorToDropBox("lowmem", null, "system_server", null,
14764                null, tag.toString(), dropBuilder.toString(), null, null);
14765        //Slog.i(TAG, "Sent to dropbox:");
14766        //Slog.i(TAG, dropBuilder.toString());
14767        synchronized (ActivityManagerService.this) {
14768            long now = SystemClock.uptimeMillis();
14769            if (mLastMemUsageReportTime < now) {
14770                mLastMemUsageReportTime = now;
14771            }
14772        }
14773    }
14774
14775    /**
14776     * Searches array of arguments for the specified string
14777     * @param args array of argument strings
14778     * @param value value to search for
14779     * @return true if the value is contained in the array
14780     */
14781    private static boolean scanArgs(String[] args, String value) {
14782        if (args != null) {
14783            for (String arg : args) {
14784                if (value.equals(arg)) {
14785                    return true;
14786                }
14787            }
14788        }
14789        return false;
14790    }
14791
14792    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14793            ContentProviderRecord cpr, boolean always) {
14794        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14795
14796        if (!inLaunching || always) {
14797            synchronized (cpr) {
14798                cpr.launchingApp = null;
14799                cpr.notifyAll();
14800            }
14801            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14802            String names[] = cpr.info.authority.split(";");
14803            for (int j = 0; j < names.length; j++) {
14804                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14805            }
14806        }
14807
14808        for (int i=0; i<cpr.connections.size(); i++) {
14809            ContentProviderConnection conn = cpr.connections.get(i);
14810            if (conn.waiting) {
14811                // If this connection is waiting for the provider, then we don't
14812                // need to mess with its process unless we are always removing
14813                // or for some reason the provider is not currently launching.
14814                if (inLaunching && !always) {
14815                    continue;
14816                }
14817            }
14818            ProcessRecord capp = conn.client;
14819            conn.dead = true;
14820            if (conn.stableCount > 0) {
14821                if (!capp.persistent && capp.thread != null
14822                        && capp.pid != 0
14823                        && capp.pid != MY_PID) {
14824                    capp.kill("depends on provider "
14825                            + cpr.name.flattenToShortString()
14826                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14827                }
14828            } else if (capp.thread != null && conn.provider.provider != null) {
14829                try {
14830                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14831                } catch (RemoteException e) {
14832                }
14833                // In the protocol here, we don't expect the client to correctly
14834                // clean up this connection, we'll just remove it.
14835                cpr.connections.remove(i);
14836                if (conn.client.conProviders.remove(conn)) {
14837                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14838                }
14839            }
14840        }
14841
14842        if (inLaunching && always) {
14843            mLaunchingProviders.remove(cpr);
14844        }
14845        return inLaunching;
14846    }
14847
14848    /**
14849     * Main code for cleaning up a process when it has gone away.  This is
14850     * called both as a result of the process dying, or directly when stopping
14851     * a process when running in single process mode.
14852     *
14853     * @return Returns true if the given process has been restarted, so the
14854     * app that was passed in must remain on the process lists.
14855     */
14856    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14857            boolean restarting, boolean allowRestart, int index) {
14858        if (index >= 0) {
14859            removeLruProcessLocked(app);
14860            ProcessList.remove(app.pid);
14861        }
14862
14863        mProcessesToGc.remove(app);
14864        mPendingPssProcesses.remove(app);
14865
14866        // Dismiss any open dialogs.
14867        if (app.crashDialog != null && !app.forceCrashReport) {
14868            app.crashDialog.dismiss();
14869            app.crashDialog = null;
14870        }
14871        if (app.anrDialog != null) {
14872            app.anrDialog.dismiss();
14873            app.anrDialog = null;
14874        }
14875        if (app.waitDialog != null) {
14876            app.waitDialog.dismiss();
14877            app.waitDialog = null;
14878        }
14879
14880        app.crashing = false;
14881        app.notResponding = false;
14882
14883        app.resetPackageList(mProcessStats);
14884        app.unlinkDeathRecipient();
14885        app.makeInactive(mProcessStats);
14886        app.waitingToKill = null;
14887        app.forcingToForeground = null;
14888        updateProcessForegroundLocked(app, false, false);
14889        app.foregroundActivities = false;
14890        app.hasShownUi = false;
14891        app.treatLikeActivity = false;
14892        app.hasAboveClient = false;
14893        app.hasClientActivities = false;
14894
14895        mServices.killServicesLocked(app, allowRestart);
14896
14897        boolean restart = false;
14898
14899        // Remove published content providers.
14900        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14901            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14902            final boolean always = app.bad || !allowRestart;
14903            if (removeDyingProviderLocked(app, cpr, always) || always) {
14904                // We left the provider in the launching list, need to
14905                // restart it.
14906                restart = true;
14907            }
14908
14909            cpr.provider = null;
14910            cpr.proc = null;
14911        }
14912        app.pubProviders.clear();
14913
14914        // Take care of any launching providers waiting for this process.
14915        if (checkAppInLaunchingProvidersLocked(app, false)) {
14916            restart = true;
14917        }
14918
14919        // Unregister from connected content providers.
14920        if (!app.conProviders.isEmpty()) {
14921            for (int i=0; i<app.conProviders.size(); i++) {
14922                ContentProviderConnection conn = app.conProviders.get(i);
14923                conn.provider.connections.remove(conn);
14924                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14925                        conn.provider.name);
14926            }
14927            app.conProviders.clear();
14928        }
14929
14930        // At this point there may be remaining entries in mLaunchingProviders
14931        // where we were the only one waiting, so they are no longer of use.
14932        // Look for these and clean up if found.
14933        // XXX Commented out for now.  Trying to figure out a way to reproduce
14934        // the actual situation to identify what is actually going on.
14935        if (false) {
14936            for (int i=0; i<mLaunchingProviders.size(); i++) {
14937                ContentProviderRecord cpr = (ContentProviderRecord)
14938                        mLaunchingProviders.get(i);
14939                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14940                    synchronized (cpr) {
14941                        cpr.launchingApp = null;
14942                        cpr.notifyAll();
14943                    }
14944                }
14945            }
14946        }
14947
14948        skipCurrentReceiverLocked(app);
14949
14950        // Unregister any receivers.
14951        for (int i=app.receivers.size()-1; i>=0; i--) {
14952            removeReceiverLocked(app.receivers.valueAt(i));
14953        }
14954        app.receivers.clear();
14955
14956        // If the app is undergoing backup, tell the backup manager about it
14957        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14958            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14959                    + mBackupTarget.appInfo + " died during backup");
14960            try {
14961                IBackupManager bm = IBackupManager.Stub.asInterface(
14962                        ServiceManager.getService(Context.BACKUP_SERVICE));
14963                bm.agentDisconnected(app.info.packageName);
14964            } catch (RemoteException e) {
14965                // can't happen; backup manager is local
14966            }
14967        }
14968
14969        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14970            ProcessChangeItem item = mPendingProcessChanges.get(i);
14971            if (item.pid == app.pid) {
14972                mPendingProcessChanges.remove(i);
14973                mAvailProcessChanges.add(item);
14974            }
14975        }
14976        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14977
14978        // If the caller is restarting this app, then leave it in its
14979        // current lists and let the caller take care of it.
14980        if (restarting) {
14981            return false;
14982        }
14983
14984        if (!app.persistent || app.isolated) {
14985            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14986                    "Removing non-persistent process during cleanup: " + app);
14987            mProcessNames.remove(app.processName, app.uid);
14988            mIsolatedProcesses.remove(app.uid);
14989            if (mHeavyWeightProcess == app) {
14990                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14991                        mHeavyWeightProcess.userId, 0));
14992                mHeavyWeightProcess = null;
14993            }
14994        } else if (!app.removed) {
14995            // This app is persistent, so we need to keep its record around.
14996            // If it is not already on the pending app list, add it there
14997            // and start a new process for it.
14998            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14999                mPersistentStartingProcesses.add(app);
15000                restart = true;
15001            }
15002        }
15003        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15004                "Clean-up removing on hold: " + app);
15005        mProcessesOnHold.remove(app);
15006
15007        if (app == mHomeProcess) {
15008            mHomeProcess = null;
15009        }
15010        if (app == mPreviousProcess) {
15011            mPreviousProcess = null;
15012        }
15013
15014        if (restart && !app.isolated) {
15015            // We have components that still need to be running in the
15016            // process, so re-launch it.
15017            if (index < 0) {
15018                ProcessList.remove(app.pid);
15019            }
15020            mProcessNames.put(app.processName, app.uid, app);
15021            startProcessLocked(app, "restart", app.processName);
15022            return true;
15023        } else if (app.pid > 0 && app.pid != MY_PID) {
15024            // Goodbye!
15025            boolean removed;
15026            synchronized (mPidsSelfLocked) {
15027                mPidsSelfLocked.remove(app.pid);
15028                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15029            }
15030            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15031            if (app.isolated) {
15032                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15033            }
15034            app.setPid(0);
15035        }
15036        return false;
15037    }
15038
15039    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15040        // Look through the content providers we are waiting to have launched,
15041        // and if any run in this process then either schedule a restart of
15042        // the process or kill the client waiting for it if this process has
15043        // gone bad.
15044        int NL = mLaunchingProviders.size();
15045        boolean restart = false;
15046        for (int i=0; i<NL; i++) {
15047            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15048            if (cpr.launchingApp == app) {
15049                if (!alwaysBad && !app.bad) {
15050                    restart = true;
15051                } else {
15052                    removeDyingProviderLocked(app, cpr, true);
15053                    // cpr should have been removed from mLaunchingProviders
15054                    NL = mLaunchingProviders.size();
15055                    i--;
15056                }
15057            }
15058        }
15059        return restart;
15060    }
15061
15062    // =========================================================
15063    // SERVICES
15064    // =========================================================
15065
15066    @Override
15067    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15068            int flags) {
15069        enforceNotIsolatedCaller("getServices");
15070        synchronized (this) {
15071            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15072        }
15073    }
15074
15075    @Override
15076    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15077        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15078        synchronized (this) {
15079            return mServices.getRunningServiceControlPanelLocked(name);
15080        }
15081    }
15082
15083    @Override
15084    public ComponentName startService(IApplicationThread caller, Intent service,
15085            String resolvedType, int userId) {
15086        enforceNotIsolatedCaller("startService");
15087        // Refuse possible leaked file descriptors
15088        if (service != null && service.hasFileDescriptors() == true) {
15089            throw new IllegalArgumentException("File descriptors passed in Intent");
15090        }
15091
15092        if (DEBUG_SERVICE)
15093            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15094        synchronized(this) {
15095            final int callingPid = Binder.getCallingPid();
15096            final int callingUid = Binder.getCallingUid();
15097            final long origId = Binder.clearCallingIdentity();
15098            ComponentName res = mServices.startServiceLocked(caller, service,
15099                    resolvedType, callingPid, callingUid, userId);
15100            Binder.restoreCallingIdentity(origId);
15101            return res;
15102        }
15103    }
15104
15105    ComponentName startServiceInPackage(int uid,
15106            Intent service, String resolvedType, int userId) {
15107        synchronized(this) {
15108            if (DEBUG_SERVICE)
15109                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15110            final long origId = Binder.clearCallingIdentity();
15111            ComponentName res = mServices.startServiceLocked(null, service,
15112                    resolvedType, -1, uid, userId);
15113            Binder.restoreCallingIdentity(origId);
15114            return res;
15115        }
15116    }
15117
15118    @Override
15119    public int stopService(IApplicationThread caller, Intent service,
15120            String resolvedType, int userId) {
15121        enforceNotIsolatedCaller("stopService");
15122        // Refuse possible leaked file descriptors
15123        if (service != null && service.hasFileDescriptors() == true) {
15124            throw new IllegalArgumentException("File descriptors passed in Intent");
15125        }
15126
15127        synchronized(this) {
15128            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15129        }
15130    }
15131
15132    @Override
15133    public IBinder peekService(Intent service, String resolvedType) {
15134        enforceNotIsolatedCaller("peekService");
15135        // Refuse possible leaked file descriptors
15136        if (service != null && service.hasFileDescriptors() == true) {
15137            throw new IllegalArgumentException("File descriptors passed in Intent");
15138        }
15139        synchronized(this) {
15140            return mServices.peekServiceLocked(service, resolvedType);
15141        }
15142    }
15143
15144    @Override
15145    public boolean stopServiceToken(ComponentName className, IBinder token,
15146            int startId) {
15147        synchronized(this) {
15148            return mServices.stopServiceTokenLocked(className, token, startId);
15149        }
15150    }
15151
15152    @Override
15153    public void setServiceForeground(ComponentName className, IBinder token,
15154            int id, Notification notification, boolean removeNotification) {
15155        synchronized(this) {
15156            mServices.setServiceForegroundLocked(className, token, id, notification,
15157                    removeNotification);
15158        }
15159    }
15160
15161    @Override
15162    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15163            boolean requireFull, String name, String callerPackage) {
15164        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15165                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15166    }
15167
15168    int unsafeConvertIncomingUser(int userId) {
15169        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15170                ? mCurrentUserId : userId;
15171    }
15172
15173    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15174            int allowMode, String name, String callerPackage) {
15175        final int callingUserId = UserHandle.getUserId(callingUid);
15176        if (callingUserId == userId) {
15177            return userId;
15178        }
15179
15180        // Note that we may be accessing mCurrentUserId outside of a lock...
15181        // shouldn't be a big deal, if this is being called outside
15182        // of a locked context there is intrinsically a race with
15183        // the value the caller will receive and someone else changing it.
15184        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15185        // we will switch to the calling user if access to the current user fails.
15186        int targetUserId = unsafeConvertIncomingUser(userId);
15187
15188        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15189            final boolean allow;
15190            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15191                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15192                // If the caller has this permission, they always pass go.  And collect $200.
15193                allow = true;
15194            } else if (allowMode == ALLOW_FULL_ONLY) {
15195                // We require full access, sucks to be you.
15196                allow = false;
15197            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15198                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15199                // If the caller does not have either permission, they are always doomed.
15200                allow = false;
15201            } else if (allowMode == ALLOW_NON_FULL) {
15202                // We are blanket allowing non-full access, you lucky caller!
15203                allow = true;
15204            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15205                // We may or may not allow this depending on whether the two users are
15206                // in the same profile.
15207                synchronized (mUserProfileGroupIdsSelfLocked) {
15208                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15209                            UserInfo.NO_PROFILE_GROUP_ID);
15210                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15211                            UserInfo.NO_PROFILE_GROUP_ID);
15212                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15213                            && callingProfile == targetProfile;
15214                }
15215            } else {
15216                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15217            }
15218            if (!allow) {
15219                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15220                    // In this case, they would like to just execute as their
15221                    // owner user instead of failing.
15222                    targetUserId = callingUserId;
15223                } else {
15224                    StringBuilder builder = new StringBuilder(128);
15225                    builder.append("Permission Denial: ");
15226                    builder.append(name);
15227                    if (callerPackage != null) {
15228                        builder.append(" from ");
15229                        builder.append(callerPackage);
15230                    }
15231                    builder.append(" asks to run as user ");
15232                    builder.append(userId);
15233                    builder.append(" but is calling from user ");
15234                    builder.append(UserHandle.getUserId(callingUid));
15235                    builder.append("; this requires ");
15236                    builder.append(INTERACT_ACROSS_USERS_FULL);
15237                    if (allowMode != ALLOW_FULL_ONLY) {
15238                        builder.append(" or ");
15239                        builder.append(INTERACT_ACROSS_USERS);
15240                    }
15241                    String msg = builder.toString();
15242                    Slog.w(TAG, msg);
15243                    throw new SecurityException(msg);
15244                }
15245            }
15246        }
15247        if (!allowAll && targetUserId < 0) {
15248            throw new IllegalArgumentException(
15249                    "Call does not support special user #" + targetUserId);
15250        }
15251        // Check shell permission
15252        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15253            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15254                    targetUserId)) {
15255                throw new SecurityException("Shell does not have permission to access user "
15256                        + targetUserId + "\n " + Debug.getCallers(3));
15257            }
15258        }
15259        return targetUserId;
15260    }
15261
15262    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15263            String className, int flags) {
15264        boolean result = false;
15265        // For apps that don't have pre-defined UIDs, check for permission
15266        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15267            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15268                if (ActivityManager.checkUidPermission(
15269                        INTERACT_ACROSS_USERS,
15270                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15271                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15272                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15273                            + " requests FLAG_SINGLE_USER, but app does not hold "
15274                            + INTERACT_ACROSS_USERS;
15275                    Slog.w(TAG, msg);
15276                    throw new SecurityException(msg);
15277                }
15278                // Permission passed
15279                result = true;
15280            }
15281        } else if ("system".equals(componentProcessName)) {
15282            result = true;
15283        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15284            // Phone app and persistent apps are allowed to export singleuser providers.
15285            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15286                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15287        }
15288        if (DEBUG_MU) {
15289            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15290                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15291        }
15292        return result;
15293    }
15294
15295    /**
15296     * Checks to see if the caller is in the same app as the singleton
15297     * component, or the component is in a special app. It allows special apps
15298     * to export singleton components but prevents exporting singleton
15299     * components for regular apps.
15300     */
15301    boolean isValidSingletonCall(int callingUid, int componentUid) {
15302        int componentAppId = UserHandle.getAppId(componentUid);
15303        return UserHandle.isSameApp(callingUid, componentUid)
15304                || componentAppId == Process.SYSTEM_UID
15305                || componentAppId == Process.PHONE_UID
15306                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15307                        == PackageManager.PERMISSION_GRANTED;
15308    }
15309
15310    public int bindService(IApplicationThread caller, IBinder token,
15311            Intent service, String resolvedType,
15312            IServiceConnection connection, int flags, int userId) {
15313        enforceNotIsolatedCaller("bindService");
15314
15315        // Refuse possible leaked file descriptors
15316        if (service != null && service.hasFileDescriptors() == true) {
15317            throw new IllegalArgumentException("File descriptors passed in Intent");
15318        }
15319
15320        synchronized(this) {
15321            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15322                    connection, flags, userId);
15323        }
15324    }
15325
15326    public boolean unbindService(IServiceConnection connection) {
15327        synchronized (this) {
15328            return mServices.unbindServiceLocked(connection);
15329        }
15330    }
15331
15332    public void publishService(IBinder token, Intent intent, IBinder service) {
15333        // Refuse possible leaked file descriptors
15334        if (intent != null && intent.hasFileDescriptors() == true) {
15335            throw new IllegalArgumentException("File descriptors passed in Intent");
15336        }
15337
15338        synchronized(this) {
15339            if (!(token instanceof ServiceRecord)) {
15340                throw new IllegalArgumentException("Invalid service token");
15341            }
15342            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15343        }
15344    }
15345
15346    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15347        // Refuse possible leaked file descriptors
15348        if (intent != null && intent.hasFileDescriptors() == true) {
15349            throw new IllegalArgumentException("File descriptors passed in Intent");
15350        }
15351
15352        synchronized(this) {
15353            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15354        }
15355    }
15356
15357    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15358        synchronized(this) {
15359            if (!(token instanceof ServiceRecord)) {
15360                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15361                throw new IllegalArgumentException("Invalid service token");
15362            }
15363            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15364        }
15365    }
15366
15367    // =========================================================
15368    // BACKUP AND RESTORE
15369    // =========================================================
15370
15371    // Cause the target app to be launched if necessary and its backup agent
15372    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15373    // activity manager to announce its creation.
15374    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15375        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15376        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15377
15378        synchronized(this) {
15379            // !!! TODO: currently no check here that we're already bound
15380            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15381            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15382            synchronized (stats) {
15383                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15384            }
15385
15386            // Backup agent is now in use, its package can't be stopped.
15387            try {
15388                AppGlobals.getPackageManager().setPackageStoppedState(
15389                        app.packageName, false, UserHandle.getUserId(app.uid));
15390            } catch (RemoteException e) {
15391            } catch (IllegalArgumentException e) {
15392                Slog.w(TAG, "Failed trying to unstop package "
15393                        + app.packageName + ": " + e);
15394            }
15395
15396            BackupRecord r = new BackupRecord(ss, app, backupMode);
15397            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15398                    ? new ComponentName(app.packageName, app.backupAgentName)
15399                    : new ComponentName("android", "FullBackupAgent");
15400            // startProcessLocked() returns existing proc's record if it's already running
15401            ProcessRecord proc = startProcessLocked(app.processName, app,
15402                    false, 0, "backup", hostingName, false, false, false);
15403            if (proc == null) {
15404                Slog.e(TAG, "Unable to start backup agent process " + r);
15405                return false;
15406            }
15407
15408            r.app = proc;
15409            mBackupTarget = r;
15410            mBackupAppName = app.packageName;
15411
15412            // Try not to kill the process during backup
15413            updateOomAdjLocked(proc);
15414
15415            // If the process is already attached, schedule the creation of the backup agent now.
15416            // If it is not yet live, this will be done when it attaches to the framework.
15417            if (proc.thread != null) {
15418                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15419                try {
15420                    proc.thread.scheduleCreateBackupAgent(app,
15421                            compatibilityInfoForPackageLocked(app), backupMode);
15422                } catch (RemoteException e) {
15423                    // Will time out on the backup manager side
15424                }
15425            } else {
15426                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15427            }
15428            // Invariants: at this point, the target app process exists and the application
15429            // is either already running or in the process of coming up.  mBackupTarget and
15430            // mBackupAppName describe the app, so that when it binds back to the AM we
15431            // know that it's scheduled for a backup-agent operation.
15432        }
15433
15434        return true;
15435    }
15436
15437    @Override
15438    public void clearPendingBackup() {
15439        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15440        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15441
15442        synchronized (this) {
15443            mBackupTarget = null;
15444            mBackupAppName = null;
15445        }
15446    }
15447
15448    // A backup agent has just come up
15449    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15450        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15451                + " = " + agent);
15452
15453        synchronized(this) {
15454            if (!agentPackageName.equals(mBackupAppName)) {
15455                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15456                return;
15457            }
15458        }
15459
15460        long oldIdent = Binder.clearCallingIdentity();
15461        try {
15462            IBackupManager bm = IBackupManager.Stub.asInterface(
15463                    ServiceManager.getService(Context.BACKUP_SERVICE));
15464            bm.agentConnected(agentPackageName, agent);
15465        } catch (RemoteException e) {
15466            // can't happen; the backup manager service is local
15467        } catch (Exception e) {
15468            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15469            e.printStackTrace();
15470        } finally {
15471            Binder.restoreCallingIdentity(oldIdent);
15472        }
15473    }
15474
15475    // done with this agent
15476    public void unbindBackupAgent(ApplicationInfo appInfo) {
15477        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15478        if (appInfo == null) {
15479            Slog.w(TAG, "unbind backup agent for null app");
15480            return;
15481        }
15482
15483        synchronized(this) {
15484            try {
15485                if (mBackupAppName == null) {
15486                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15487                    return;
15488                }
15489
15490                if (!mBackupAppName.equals(appInfo.packageName)) {
15491                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15492                    return;
15493                }
15494
15495                // Not backing this app up any more; reset its OOM adjustment
15496                final ProcessRecord proc = mBackupTarget.app;
15497                updateOomAdjLocked(proc);
15498
15499                // If the app crashed during backup, 'thread' will be null here
15500                if (proc.thread != null) {
15501                    try {
15502                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15503                                compatibilityInfoForPackageLocked(appInfo));
15504                    } catch (Exception e) {
15505                        Slog.e(TAG, "Exception when unbinding backup agent:");
15506                        e.printStackTrace();
15507                    }
15508                }
15509            } finally {
15510                mBackupTarget = null;
15511                mBackupAppName = null;
15512            }
15513        }
15514    }
15515    // =========================================================
15516    // BROADCASTS
15517    // =========================================================
15518
15519    private final List getStickiesLocked(String action, IntentFilter filter,
15520            List cur, int userId) {
15521        final ContentResolver resolver = mContext.getContentResolver();
15522        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15523        if (stickies == null) {
15524            return cur;
15525        }
15526        final ArrayList<Intent> list = stickies.get(action);
15527        if (list == null) {
15528            return cur;
15529        }
15530        int N = list.size();
15531        for (int i=0; i<N; i++) {
15532            Intent intent = list.get(i);
15533            if (filter.match(resolver, intent, true, TAG) >= 0) {
15534                if (cur == null) {
15535                    cur = new ArrayList<Intent>();
15536                }
15537                cur.add(intent);
15538            }
15539        }
15540        return cur;
15541    }
15542
15543    boolean isPendingBroadcastProcessLocked(int pid) {
15544        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15545                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15546    }
15547
15548    void skipPendingBroadcastLocked(int pid) {
15549            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15550            for (BroadcastQueue queue : mBroadcastQueues) {
15551                queue.skipPendingBroadcastLocked(pid);
15552            }
15553    }
15554
15555    // The app just attached; send any pending broadcasts that it should receive
15556    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15557        boolean didSomething = false;
15558        for (BroadcastQueue queue : mBroadcastQueues) {
15559            didSomething |= queue.sendPendingBroadcastsLocked(app);
15560        }
15561        return didSomething;
15562    }
15563
15564    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15565            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15566        enforceNotIsolatedCaller("registerReceiver");
15567        int callingUid;
15568        int callingPid;
15569        synchronized(this) {
15570            ProcessRecord callerApp = null;
15571            if (caller != null) {
15572                callerApp = getRecordForAppLocked(caller);
15573                if (callerApp == null) {
15574                    throw new SecurityException(
15575                            "Unable to find app for caller " + caller
15576                            + " (pid=" + Binder.getCallingPid()
15577                            + ") when registering receiver " + receiver);
15578                }
15579                if (callerApp.info.uid != Process.SYSTEM_UID &&
15580                        !callerApp.pkgList.containsKey(callerPackage) &&
15581                        !"android".equals(callerPackage)) {
15582                    throw new SecurityException("Given caller package " + callerPackage
15583                            + " is not running in process " + callerApp);
15584                }
15585                callingUid = callerApp.info.uid;
15586                callingPid = callerApp.pid;
15587            } else {
15588                callerPackage = null;
15589                callingUid = Binder.getCallingUid();
15590                callingPid = Binder.getCallingPid();
15591            }
15592
15593            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15594                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15595
15596            List allSticky = null;
15597
15598            // Look for any matching sticky broadcasts...
15599            Iterator actions = filter.actionsIterator();
15600            if (actions != null) {
15601                while (actions.hasNext()) {
15602                    String action = (String)actions.next();
15603                    allSticky = getStickiesLocked(action, filter, allSticky,
15604                            UserHandle.USER_ALL);
15605                    allSticky = getStickiesLocked(action, filter, allSticky,
15606                            UserHandle.getUserId(callingUid));
15607                }
15608            } else {
15609                allSticky = getStickiesLocked(null, filter, allSticky,
15610                        UserHandle.USER_ALL);
15611                allSticky = getStickiesLocked(null, filter, allSticky,
15612                        UserHandle.getUserId(callingUid));
15613            }
15614
15615            // The first sticky in the list is returned directly back to
15616            // the client.
15617            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15618
15619            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15620                    + ": " + sticky);
15621
15622            if (receiver == null) {
15623                return sticky;
15624            }
15625
15626            ReceiverList rl
15627                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15628            if (rl == null) {
15629                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15630                        userId, receiver);
15631                if (rl.app != null) {
15632                    rl.app.receivers.add(rl);
15633                } else {
15634                    try {
15635                        receiver.asBinder().linkToDeath(rl, 0);
15636                    } catch (RemoteException e) {
15637                        return sticky;
15638                    }
15639                    rl.linkedToDeath = true;
15640                }
15641                mRegisteredReceivers.put(receiver.asBinder(), rl);
15642            } else if (rl.uid != callingUid) {
15643                throw new IllegalArgumentException(
15644                        "Receiver requested to register for uid " + callingUid
15645                        + " was previously registered for uid " + rl.uid);
15646            } else if (rl.pid != callingPid) {
15647                throw new IllegalArgumentException(
15648                        "Receiver requested to register for pid " + callingPid
15649                        + " was previously registered for pid " + rl.pid);
15650            } else if (rl.userId != userId) {
15651                throw new IllegalArgumentException(
15652                        "Receiver requested to register for user " + userId
15653                        + " was previously registered for user " + rl.userId);
15654            }
15655            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15656                    permission, callingUid, userId);
15657            rl.add(bf);
15658            if (!bf.debugCheck()) {
15659                Slog.w(TAG, "==> For Dynamic broadast");
15660            }
15661            mReceiverResolver.addFilter(bf);
15662
15663            // Enqueue broadcasts for all existing stickies that match
15664            // this filter.
15665            if (allSticky != null) {
15666                ArrayList receivers = new ArrayList();
15667                receivers.add(bf);
15668
15669                int N = allSticky.size();
15670                for (int i=0; i<N; i++) {
15671                    Intent intent = (Intent)allSticky.get(i);
15672                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15673                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15674                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15675                            null, null, false, true, true, -1);
15676                    queue.enqueueParallelBroadcastLocked(r);
15677                    queue.scheduleBroadcastsLocked();
15678                }
15679            }
15680
15681            return sticky;
15682        }
15683    }
15684
15685    public void unregisterReceiver(IIntentReceiver receiver) {
15686        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15687
15688        final long origId = Binder.clearCallingIdentity();
15689        try {
15690            boolean doTrim = false;
15691
15692            synchronized(this) {
15693                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15694                if (rl != null) {
15695                    if (rl.curBroadcast != null) {
15696                        BroadcastRecord r = rl.curBroadcast;
15697                        final boolean doNext = finishReceiverLocked(
15698                                receiver.asBinder(), r.resultCode, r.resultData,
15699                                r.resultExtras, r.resultAbort);
15700                        if (doNext) {
15701                            doTrim = true;
15702                            r.queue.processNextBroadcast(false);
15703                        }
15704                    }
15705
15706                    if (rl.app != null) {
15707                        rl.app.receivers.remove(rl);
15708                    }
15709                    removeReceiverLocked(rl);
15710                    if (rl.linkedToDeath) {
15711                        rl.linkedToDeath = false;
15712                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15713                    }
15714                }
15715            }
15716
15717            // If we actually concluded any broadcasts, we might now be able
15718            // to trim the recipients' apps from our working set
15719            if (doTrim) {
15720                trimApplications();
15721                return;
15722            }
15723
15724        } finally {
15725            Binder.restoreCallingIdentity(origId);
15726        }
15727    }
15728
15729    void removeReceiverLocked(ReceiverList rl) {
15730        mRegisteredReceivers.remove(rl.receiver.asBinder());
15731        int N = rl.size();
15732        for (int i=0; i<N; i++) {
15733            mReceiverResolver.removeFilter(rl.get(i));
15734        }
15735    }
15736
15737    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15738        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15739            ProcessRecord r = mLruProcesses.get(i);
15740            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15741                try {
15742                    r.thread.dispatchPackageBroadcast(cmd, packages);
15743                } catch (RemoteException ex) {
15744                }
15745            }
15746        }
15747    }
15748
15749    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15750            int callingUid, int[] users) {
15751        List<ResolveInfo> receivers = null;
15752        try {
15753            HashSet<ComponentName> singleUserReceivers = null;
15754            boolean scannedFirstReceivers = false;
15755            for (int user : users) {
15756                // Skip users that have Shell restrictions
15757                if (callingUid == Process.SHELL_UID
15758                        && getUserManagerLocked().hasUserRestriction(
15759                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15760                    continue;
15761                }
15762                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15763                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15764                if (user != 0 && newReceivers != null) {
15765                    // If this is not the primary user, we need to check for
15766                    // any receivers that should be filtered out.
15767                    for (int i=0; i<newReceivers.size(); i++) {
15768                        ResolveInfo ri = newReceivers.get(i);
15769                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15770                            newReceivers.remove(i);
15771                            i--;
15772                        }
15773                    }
15774                }
15775                if (newReceivers != null && newReceivers.size() == 0) {
15776                    newReceivers = null;
15777                }
15778                if (receivers == null) {
15779                    receivers = newReceivers;
15780                } else if (newReceivers != null) {
15781                    // We need to concatenate the additional receivers
15782                    // found with what we have do far.  This would be easy,
15783                    // but we also need to de-dup any receivers that are
15784                    // singleUser.
15785                    if (!scannedFirstReceivers) {
15786                        // Collect any single user receivers we had already retrieved.
15787                        scannedFirstReceivers = true;
15788                        for (int i=0; i<receivers.size(); i++) {
15789                            ResolveInfo ri = receivers.get(i);
15790                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15791                                ComponentName cn = new ComponentName(
15792                                        ri.activityInfo.packageName, ri.activityInfo.name);
15793                                if (singleUserReceivers == null) {
15794                                    singleUserReceivers = new HashSet<ComponentName>();
15795                                }
15796                                singleUserReceivers.add(cn);
15797                            }
15798                        }
15799                    }
15800                    // Add the new results to the existing results, tracking
15801                    // and de-dupping single user receivers.
15802                    for (int i=0; i<newReceivers.size(); i++) {
15803                        ResolveInfo ri = newReceivers.get(i);
15804                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15805                            ComponentName cn = new ComponentName(
15806                                    ri.activityInfo.packageName, ri.activityInfo.name);
15807                            if (singleUserReceivers == null) {
15808                                singleUserReceivers = new HashSet<ComponentName>();
15809                            }
15810                            if (!singleUserReceivers.contains(cn)) {
15811                                singleUserReceivers.add(cn);
15812                                receivers.add(ri);
15813                            }
15814                        } else {
15815                            receivers.add(ri);
15816                        }
15817                    }
15818                }
15819            }
15820        } catch (RemoteException ex) {
15821            // pm is in same process, this will never happen.
15822        }
15823        return receivers;
15824    }
15825
15826    private final int broadcastIntentLocked(ProcessRecord callerApp,
15827            String callerPackage, Intent intent, String resolvedType,
15828            IIntentReceiver resultTo, int resultCode, String resultData,
15829            Bundle map, String requiredPermission, int appOp,
15830            boolean ordered, boolean sticky, int callingPid, int callingUid,
15831            int userId) {
15832        intent = new Intent(intent);
15833
15834        // By default broadcasts do not go to stopped apps.
15835        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15836
15837        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15838            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15839            + " ordered=" + ordered + " userid=" + userId);
15840        if ((resultTo != null) && !ordered) {
15841            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15842        }
15843
15844        userId = handleIncomingUser(callingPid, callingUid, userId,
15845                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15846
15847        // Make sure that the user who is receiving this broadcast is running.
15848        // If not, we will just skip it. Make an exception for shutdown broadcasts
15849        // and upgrade steps.
15850
15851        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15852            if ((callingUid != Process.SYSTEM_UID
15853                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15854                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15855                Slog.w(TAG, "Skipping broadcast of " + intent
15856                        + ": user " + userId + " is stopped");
15857                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15858            }
15859        }
15860
15861        /*
15862         * Prevent non-system code (defined here to be non-persistent
15863         * processes) from sending protected broadcasts.
15864         */
15865        int callingAppId = UserHandle.getAppId(callingUid);
15866        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15867            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15868            || callingAppId == Process.NFC_UID || callingUid == 0) {
15869            // Always okay.
15870        } else if (callerApp == null || !callerApp.persistent) {
15871            try {
15872                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15873                        intent.getAction())) {
15874                    String msg = "Permission Denial: not allowed to send broadcast "
15875                            + intent.getAction() + " from pid="
15876                            + callingPid + ", uid=" + callingUid;
15877                    Slog.w(TAG, msg);
15878                    throw new SecurityException(msg);
15879                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15880                    // Special case for compatibility: we don't want apps to send this,
15881                    // but historically it has not been protected and apps may be using it
15882                    // to poke their own app widget.  So, instead of making it protected,
15883                    // just limit it to the caller.
15884                    if (callerApp == null) {
15885                        String msg = "Permission Denial: not allowed to send broadcast "
15886                                + intent.getAction() + " from unknown caller.";
15887                        Slog.w(TAG, msg);
15888                        throw new SecurityException(msg);
15889                    } else if (intent.getComponent() != null) {
15890                        // They are good enough to send to an explicit component...  verify
15891                        // it is being sent to the calling app.
15892                        if (!intent.getComponent().getPackageName().equals(
15893                                callerApp.info.packageName)) {
15894                            String msg = "Permission Denial: not allowed to send broadcast "
15895                                    + intent.getAction() + " to "
15896                                    + intent.getComponent().getPackageName() + " from "
15897                                    + callerApp.info.packageName;
15898                            Slog.w(TAG, msg);
15899                            throw new SecurityException(msg);
15900                        }
15901                    } else {
15902                        // Limit broadcast to their own package.
15903                        intent.setPackage(callerApp.info.packageName);
15904                    }
15905                }
15906            } catch (RemoteException e) {
15907                Slog.w(TAG, "Remote exception", e);
15908                return ActivityManager.BROADCAST_SUCCESS;
15909            }
15910        }
15911
15912        final String action = intent.getAction();
15913        if (action != null) {
15914            switch (action) {
15915                case Intent.ACTION_UID_REMOVED:
15916                case Intent.ACTION_PACKAGE_REMOVED:
15917                case Intent.ACTION_PACKAGE_CHANGED:
15918                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15919                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15920                    // Handle special intents: if this broadcast is from the package
15921                    // manager about a package being removed, we need to remove all of
15922                    // its activities from the history stack.
15923                    if (checkComponentPermission(
15924                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15925                            callingPid, callingUid, -1, true)
15926                            != PackageManager.PERMISSION_GRANTED) {
15927                        String msg = "Permission Denial: " + intent.getAction()
15928                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15929                                + ", uid=" + callingUid + ")"
15930                                + " requires "
15931                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15932                        Slog.w(TAG, msg);
15933                        throw new SecurityException(msg);
15934                    }
15935                    switch (action) {
15936                        case Intent.ACTION_UID_REMOVED:
15937                            final Bundle intentExtras = intent.getExtras();
15938                            final int uid = intentExtras != null
15939                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15940                            if (uid >= 0) {
15941                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15942                                synchronized (bs) {
15943                                    bs.removeUidStatsLocked(uid);
15944                                }
15945                                mAppOpsService.uidRemoved(uid);
15946                            }
15947                            break;
15948                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15949                            // If resources are unavailable just force stop all those packages
15950                            // and flush the attribute cache as well.
15951                            String list[] =
15952                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15953                            if (list != null && list.length > 0) {
15954                                for (int i = 0; i < list.length; i++) {
15955                                    forceStopPackageLocked(list[i], -1, false, true, true,
15956                                            false, false, userId, "storage unmount");
15957                                }
15958                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15959                                sendPackageBroadcastLocked(
15960                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15961                                        userId);
15962                            }
15963                            break;
15964                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15965                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15966                            break;
15967                        case Intent.ACTION_PACKAGE_REMOVED:
15968                        case Intent.ACTION_PACKAGE_CHANGED:
15969                            Uri data = intent.getData();
15970                            String ssp;
15971                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15972                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15973                                boolean fullUninstall = removed &&
15974                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15975                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15976                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15977                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15978                                            false, true, true, false, fullUninstall, userId,
15979                                            removed ? "pkg removed" : "pkg changed");
15980                                }
15981                                if (removed) {
15982                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15983                                            new String[] {ssp}, userId);
15984                                    if (fullUninstall) {
15985                                        mAppOpsService.packageRemoved(
15986                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15987
15988                                        // Remove all permissions granted from/to this package
15989                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15990
15991                                        removeTasksByPackageNameLocked(ssp, userId);
15992                                        if (userId == UserHandle.USER_OWNER) {
15993                                            mTaskPersister.removeFromPackageCache(ssp);
15994                                        }
15995                                    }
15996                                } else {
15997                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15998                                    if (userId == UserHandle.USER_OWNER) {
15999                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16000                                    }
16001                                }
16002                            }
16003                            break;
16004                    }
16005                    break;
16006                case Intent.ACTION_PACKAGE_ADDED:
16007                    // Special case for adding a package: by default turn on compatibility mode.
16008                    Uri data = intent.getData();
16009                    String ssp;
16010                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16011                        final boolean replacing =
16012                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16013                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16014
16015                        if (replacing) {
16016                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16017                        }
16018                        if (userId == UserHandle.USER_OWNER) {
16019                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16020                        }
16021                    }
16022                    break;
16023                case Intent.ACTION_TIMEZONE_CHANGED:
16024                    // If this is the time zone changed action, queue up a message that will reset
16025                    // the timezone of all currently running processes. This message will get
16026                    // queued up before the broadcast happens.
16027                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16028                    break;
16029                case Intent.ACTION_TIME_CHANGED:
16030                    // If the user set the time, let all running processes know.
16031                    final int is24Hour =
16032                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16033                                    : 0;
16034                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16035                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16036                    synchronized (stats) {
16037                        stats.noteCurrentTimeChangedLocked();
16038                    }
16039                    break;
16040                case Intent.ACTION_CLEAR_DNS_CACHE:
16041                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16042                    break;
16043                case Proxy.PROXY_CHANGE_ACTION:
16044                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16045                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16046                    break;
16047            }
16048        }
16049
16050        // Add to the sticky list if requested.
16051        if (sticky) {
16052            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16053                    callingPid, callingUid)
16054                    != PackageManager.PERMISSION_GRANTED) {
16055                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16056                        + callingPid + ", uid=" + callingUid
16057                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16058                Slog.w(TAG, msg);
16059                throw new SecurityException(msg);
16060            }
16061            if (requiredPermission != null) {
16062                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16063                        + " and enforce permission " + requiredPermission);
16064                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16065            }
16066            if (intent.getComponent() != null) {
16067                throw new SecurityException(
16068                        "Sticky broadcasts can't target a specific component");
16069            }
16070            // We use userId directly here, since the "all" target is maintained
16071            // as a separate set of sticky broadcasts.
16072            if (userId != UserHandle.USER_ALL) {
16073                // But first, if this is not a broadcast to all users, then
16074                // make sure it doesn't conflict with an existing broadcast to
16075                // all users.
16076                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16077                        UserHandle.USER_ALL);
16078                if (stickies != null) {
16079                    ArrayList<Intent> list = stickies.get(intent.getAction());
16080                    if (list != null) {
16081                        int N = list.size();
16082                        int i;
16083                        for (i=0; i<N; i++) {
16084                            if (intent.filterEquals(list.get(i))) {
16085                                throw new IllegalArgumentException(
16086                                        "Sticky broadcast " + intent + " for user "
16087                                        + userId + " conflicts with existing global broadcast");
16088                            }
16089                        }
16090                    }
16091                }
16092            }
16093            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16094            if (stickies == null) {
16095                stickies = new ArrayMap<String, ArrayList<Intent>>();
16096                mStickyBroadcasts.put(userId, stickies);
16097            }
16098            ArrayList<Intent> list = stickies.get(intent.getAction());
16099            if (list == null) {
16100                list = new ArrayList<Intent>();
16101                stickies.put(intent.getAction(), list);
16102            }
16103            int N = list.size();
16104            int i;
16105            for (i=0; i<N; i++) {
16106                if (intent.filterEquals(list.get(i))) {
16107                    // This sticky already exists, replace it.
16108                    list.set(i, new Intent(intent));
16109                    break;
16110                }
16111            }
16112            if (i >= N) {
16113                list.add(new Intent(intent));
16114            }
16115        }
16116
16117        int[] users;
16118        if (userId == UserHandle.USER_ALL) {
16119            // Caller wants broadcast to go to all started users.
16120            users = mStartedUserArray;
16121        } else {
16122            // Caller wants broadcast to go to one specific user.
16123            users = new int[] {userId};
16124        }
16125
16126        // Figure out who all will receive this broadcast.
16127        List receivers = null;
16128        List<BroadcastFilter> registeredReceivers = null;
16129        // Need to resolve the intent to interested receivers...
16130        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16131                 == 0) {
16132            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16133        }
16134        if (intent.getComponent() == null) {
16135            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16136                // Query one target user at a time, excluding shell-restricted users
16137                UserManagerService ums = getUserManagerLocked();
16138                for (int i = 0; i < users.length; i++) {
16139                    if (ums.hasUserRestriction(
16140                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16141                        continue;
16142                    }
16143                    List<BroadcastFilter> registeredReceiversForUser =
16144                            mReceiverResolver.queryIntent(intent,
16145                                    resolvedType, false, users[i]);
16146                    if (registeredReceivers == null) {
16147                        registeredReceivers = registeredReceiversForUser;
16148                    } else if (registeredReceiversForUser != null) {
16149                        registeredReceivers.addAll(registeredReceiversForUser);
16150                    }
16151                }
16152            } else {
16153                registeredReceivers = mReceiverResolver.queryIntent(intent,
16154                        resolvedType, false, userId);
16155            }
16156        }
16157
16158        final boolean replacePending =
16159                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16160
16161        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16162                + " replacePending=" + replacePending);
16163
16164        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16165        if (!ordered && NR > 0) {
16166            // If we are not serializing this broadcast, then send the
16167            // registered receivers separately so they don't wait for the
16168            // components to be launched.
16169            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16170            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16171                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16172                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16173                    ordered, sticky, false, userId);
16174            if (DEBUG_BROADCAST) Slog.v(
16175                    TAG, "Enqueueing parallel broadcast " + r);
16176            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16177            if (!replaced) {
16178                queue.enqueueParallelBroadcastLocked(r);
16179                queue.scheduleBroadcastsLocked();
16180            }
16181            registeredReceivers = null;
16182            NR = 0;
16183        }
16184
16185        // Merge into one list.
16186        int ir = 0;
16187        if (receivers != null) {
16188            // A special case for PACKAGE_ADDED: do not allow the package
16189            // being added to see this broadcast.  This prevents them from
16190            // using this as a back door to get run as soon as they are
16191            // installed.  Maybe in the future we want to have a special install
16192            // broadcast or such for apps, but we'd like to deliberately make
16193            // this decision.
16194            String skipPackages[] = null;
16195            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16196                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16197                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16198                Uri data = intent.getData();
16199                if (data != null) {
16200                    String pkgName = data.getSchemeSpecificPart();
16201                    if (pkgName != null) {
16202                        skipPackages = new String[] { pkgName };
16203                    }
16204                }
16205            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16206                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16207            }
16208            if (skipPackages != null && (skipPackages.length > 0)) {
16209                for (String skipPackage : skipPackages) {
16210                    if (skipPackage != null) {
16211                        int NT = receivers.size();
16212                        for (int it=0; it<NT; it++) {
16213                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16214                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16215                                receivers.remove(it);
16216                                it--;
16217                                NT--;
16218                            }
16219                        }
16220                    }
16221                }
16222            }
16223
16224            int NT = receivers != null ? receivers.size() : 0;
16225            int it = 0;
16226            ResolveInfo curt = null;
16227            BroadcastFilter curr = null;
16228            while (it < NT && ir < NR) {
16229                if (curt == null) {
16230                    curt = (ResolveInfo)receivers.get(it);
16231                }
16232                if (curr == null) {
16233                    curr = registeredReceivers.get(ir);
16234                }
16235                if (curr.getPriority() >= curt.priority) {
16236                    // Insert this broadcast record into the final list.
16237                    receivers.add(it, curr);
16238                    ir++;
16239                    curr = null;
16240                    it++;
16241                    NT++;
16242                } else {
16243                    // Skip to the next ResolveInfo in the final list.
16244                    it++;
16245                    curt = null;
16246                }
16247            }
16248        }
16249        while (ir < NR) {
16250            if (receivers == null) {
16251                receivers = new ArrayList();
16252            }
16253            receivers.add(registeredReceivers.get(ir));
16254            ir++;
16255        }
16256
16257        if ((receivers != null && receivers.size() > 0)
16258                || resultTo != null) {
16259            BroadcastQueue queue = broadcastQueueForIntent(intent);
16260            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16261                    callerPackage, callingPid, callingUid, resolvedType,
16262                    requiredPermission, appOp, receivers, resultTo, resultCode,
16263                    resultData, map, ordered, sticky, false, userId);
16264            if (DEBUG_BROADCAST) Slog.v(
16265                    TAG, "Enqueueing ordered broadcast " + r
16266                    + ": prev had " + queue.mOrderedBroadcasts.size());
16267            if (DEBUG_BROADCAST) {
16268                int seq = r.intent.getIntExtra("seq", -1);
16269                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16270            }
16271            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16272            if (!replaced) {
16273                queue.enqueueOrderedBroadcastLocked(r);
16274                queue.scheduleBroadcastsLocked();
16275            }
16276        }
16277
16278        return ActivityManager.BROADCAST_SUCCESS;
16279    }
16280
16281    final Intent verifyBroadcastLocked(Intent intent) {
16282        // Refuse possible leaked file descriptors
16283        if (intent != null && intent.hasFileDescriptors() == true) {
16284            throw new IllegalArgumentException("File descriptors passed in Intent");
16285        }
16286
16287        int flags = intent.getFlags();
16288
16289        if (!mProcessesReady) {
16290            // if the caller really truly claims to know what they're doing, go
16291            // ahead and allow the broadcast without launching any receivers
16292            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16293                intent = new Intent(intent);
16294                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16295            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16296                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16297                        + " before boot completion");
16298                throw new IllegalStateException("Cannot broadcast before boot completed");
16299            }
16300        }
16301
16302        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16303            throw new IllegalArgumentException(
16304                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16305        }
16306
16307        return intent;
16308    }
16309
16310    public final int broadcastIntent(IApplicationThread caller,
16311            Intent intent, String resolvedType, IIntentReceiver resultTo,
16312            int resultCode, String resultData, Bundle map,
16313            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16314        enforceNotIsolatedCaller("broadcastIntent");
16315        synchronized(this) {
16316            intent = verifyBroadcastLocked(intent);
16317
16318            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16319            final int callingPid = Binder.getCallingPid();
16320            final int callingUid = Binder.getCallingUid();
16321            final long origId = Binder.clearCallingIdentity();
16322            int res = broadcastIntentLocked(callerApp,
16323                    callerApp != null ? callerApp.info.packageName : null,
16324                    intent, resolvedType, resultTo,
16325                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16326                    callingPid, callingUid, userId);
16327            Binder.restoreCallingIdentity(origId);
16328            return res;
16329        }
16330    }
16331
16332    int broadcastIntentInPackage(String packageName, int uid,
16333            Intent intent, String resolvedType, IIntentReceiver resultTo,
16334            int resultCode, String resultData, Bundle map,
16335            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16336        synchronized(this) {
16337            intent = verifyBroadcastLocked(intent);
16338
16339            final long origId = Binder.clearCallingIdentity();
16340            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16341                    resultTo, resultCode, resultData, map, requiredPermission,
16342                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16343            Binder.restoreCallingIdentity(origId);
16344            return res;
16345        }
16346    }
16347
16348    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16349        // Refuse possible leaked file descriptors
16350        if (intent != null && intent.hasFileDescriptors() == true) {
16351            throw new IllegalArgumentException("File descriptors passed in Intent");
16352        }
16353
16354        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16355                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16356
16357        synchronized(this) {
16358            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16359                    != PackageManager.PERMISSION_GRANTED) {
16360                String msg = "Permission Denial: unbroadcastIntent() from pid="
16361                        + Binder.getCallingPid()
16362                        + ", uid=" + Binder.getCallingUid()
16363                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16364                Slog.w(TAG, msg);
16365                throw new SecurityException(msg);
16366            }
16367            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16368            if (stickies != null) {
16369                ArrayList<Intent> list = stickies.get(intent.getAction());
16370                if (list != null) {
16371                    int N = list.size();
16372                    int i;
16373                    for (i=0; i<N; i++) {
16374                        if (intent.filterEquals(list.get(i))) {
16375                            list.remove(i);
16376                            break;
16377                        }
16378                    }
16379                    if (list.size() <= 0) {
16380                        stickies.remove(intent.getAction());
16381                    }
16382                }
16383                if (stickies.size() <= 0) {
16384                    mStickyBroadcasts.remove(userId);
16385                }
16386            }
16387        }
16388    }
16389
16390    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16391            String resultData, Bundle resultExtras, boolean resultAbort) {
16392        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16393        if (r == null) {
16394            Slog.w(TAG, "finishReceiver called but not found on queue");
16395            return false;
16396        }
16397
16398        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16399    }
16400
16401    void backgroundServicesFinishedLocked(int userId) {
16402        for (BroadcastQueue queue : mBroadcastQueues) {
16403            queue.backgroundServicesFinishedLocked(userId);
16404        }
16405    }
16406
16407    public void finishReceiver(IBinder who, int resultCode, String resultData,
16408            Bundle resultExtras, boolean resultAbort) {
16409        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16410
16411        // Refuse possible leaked file descriptors
16412        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16413            throw new IllegalArgumentException("File descriptors passed in Bundle");
16414        }
16415
16416        final long origId = Binder.clearCallingIdentity();
16417        try {
16418            boolean doNext = false;
16419            BroadcastRecord r;
16420
16421            synchronized(this) {
16422                r = broadcastRecordForReceiverLocked(who);
16423                if (r != null) {
16424                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16425                        resultData, resultExtras, resultAbort, true);
16426                }
16427            }
16428
16429            if (doNext) {
16430                r.queue.processNextBroadcast(false);
16431            }
16432            trimApplications();
16433        } finally {
16434            Binder.restoreCallingIdentity(origId);
16435        }
16436    }
16437
16438    // =========================================================
16439    // INSTRUMENTATION
16440    // =========================================================
16441
16442    public boolean startInstrumentation(ComponentName className,
16443            String profileFile, int flags, Bundle arguments,
16444            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16445            int userId, String abiOverride) {
16446        enforceNotIsolatedCaller("startInstrumentation");
16447        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16448                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16449        // Refuse possible leaked file descriptors
16450        if (arguments != null && arguments.hasFileDescriptors()) {
16451            throw new IllegalArgumentException("File descriptors passed in Bundle");
16452        }
16453
16454        synchronized(this) {
16455            InstrumentationInfo ii = null;
16456            ApplicationInfo ai = null;
16457            try {
16458                ii = mContext.getPackageManager().getInstrumentationInfo(
16459                    className, STOCK_PM_FLAGS);
16460                ai = AppGlobals.getPackageManager().getApplicationInfo(
16461                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16462            } catch (PackageManager.NameNotFoundException e) {
16463            } catch (RemoteException e) {
16464            }
16465            if (ii == null) {
16466                reportStartInstrumentationFailure(watcher, className,
16467                        "Unable to find instrumentation info for: " + className);
16468                return false;
16469            }
16470            if (ai == null) {
16471                reportStartInstrumentationFailure(watcher, className,
16472                        "Unable to find instrumentation target package: " + ii.targetPackage);
16473                return false;
16474            }
16475
16476            int match = mContext.getPackageManager().checkSignatures(
16477                    ii.targetPackage, ii.packageName);
16478            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16479                String msg = "Permission Denial: starting instrumentation "
16480                        + className + " from pid="
16481                        + Binder.getCallingPid()
16482                        + ", uid=" + Binder.getCallingPid()
16483                        + " not allowed because package " + ii.packageName
16484                        + " does not have a signature matching the target "
16485                        + ii.targetPackage;
16486                reportStartInstrumentationFailure(watcher, className, msg);
16487                throw new SecurityException(msg);
16488            }
16489
16490            final long origId = Binder.clearCallingIdentity();
16491            // Instrumentation can kill and relaunch even persistent processes
16492            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16493                    "start instr");
16494            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16495            app.instrumentationClass = className;
16496            app.instrumentationInfo = ai;
16497            app.instrumentationProfileFile = profileFile;
16498            app.instrumentationArguments = arguments;
16499            app.instrumentationWatcher = watcher;
16500            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16501            app.instrumentationResultClass = className;
16502            Binder.restoreCallingIdentity(origId);
16503        }
16504
16505        return true;
16506    }
16507
16508    /**
16509     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16510     * error to the logs, but if somebody is watching, send the report there too.  This enables
16511     * the "am" command to report errors with more information.
16512     *
16513     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16514     * @param cn The component name of the instrumentation.
16515     * @param report The error report.
16516     */
16517    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16518            ComponentName cn, String report) {
16519        Slog.w(TAG, report);
16520        try {
16521            if (watcher != null) {
16522                Bundle results = new Bundle();
16523                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16524                results.putString("Error", report);
16525                watcher.instrumentationStatus(cn, -1, results);
16526            }
16527        } catch (RemoteException e) {
16528            Slog.w(TAG, e);
16529        }
16530    }
16531
16532    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16533        if (app.instrumentationWatcher != null) {
16534            try {
16535                // NOTE:  IInstrumentationWatcher *must* be oneway here
16536                app.instrumentationWatcher.instrumentationFinished(
16537                    app.instrumentationClass,
16538                    resultCode,
16539                    results);
16540            } catch (RemoteException e) {
16541            }
16542        }
16543        if (app.instrumentationUiAutomationConnection != null) {
16544            try {
16545                app.instrumentationUiAutomationConnection.shutdown();
16546            } catch (RemoteException re) {
16547                /* ignore */
16548            }
16549            // Only a UiAutomation can set this flag and now that
16550            // it is finished we make sure it is reset to its default.
16551            mUserIsMonkey = false;
16552        }
16553        app.instrumentationWatcher = null;
16554        app.instrumentationUiAutomationConnection = null;
16555        app.instrumentationClass = null;
16556        app.instrumentationInfo = null;
16557        app.instrumentationProfileFile = null;
16558        app.instrumentationArguments = null;
16559
16560        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16561                "finished inst");
16562    }
16563
16564    public void finishInstrumentation(IApplicationThread target,
16565            int resultCode, Bundle results) {
16566        int userId = UserHandle.getCallingUserId();
16567        // Refuse possible leaked file descriptors
16568        if (results != null && results.hasFileDescriptors()) {
16569            throw new IllegalArgumentException("File descriptors passed in Intent");
16570        }
16571
16572        synchronized(this) {
16573            ProcessRecord app = getRecordForAppLocked(target);
16574            if (app == null) {
16575                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16576                return;
16577            }
16578            final long origId = Binder.clearCallingIdentity();
16579            finishInstrumentationLocked(app, resultCode, results);
16580            Binder.restoreCallingIdentity(origId);
16581        }
16582    }
16583
16584    // =========================================================
16585    // CONFIGURATION
16586    // =========================================================
16587
16588    public ConfigurationInfo getDeviceConfigurationInfo() {
16589        ConfigurationInfo config = new ConfigurationInfo();
16590        synchronized (this) {
16591            config.reqTouchScreen = mConfiguration.touchscreen;
16592            config.reqKeyboardType = mConfiguration.keyboard;
16593            config.reqNavigation = mConfiguration.navigation;
16594            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16595                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16596                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16597            }
16598            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16599                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16600                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16601            }
16602            config.reqGlEsVersion = GL_ES_VERSION;
16603        }
16604        return config;
16605    }
16606
16607    ActivityStack getFocusedStack() {
16608        return mStackSupervisor.getFocusedStack();
16609    }
16610
16611    public Configuration getConfiguration() {
16612        Configuration ci;
16613        synchronized(this) {
16614            ci = new Configuration(mConfiguration);
16615            ci.userSetLocale = false;
16616        }
16617        return ci;
16618    }
16619
16620    public void updatePersistentConfiguration(Configuration values) {
16621        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16622                "updateConfiguration()");
16623        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16624                "updateConfiguration()");
16625        if (values == null) {
16626            throw new NullPointerException("Configuration must not be null");
16627        }
16628
16629        synchronized(this) {
16630            final long origId = Binder.clearCallingIdentity();
16631            updateConfigurationLocked(values, null, true, false);
16632            Binder.restoreCallingIdentity(origId);
16633        }
16634    }
16635
16636    public void updateConfiguration(Configuration values) {
16637        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16638                "updateConfiguration()");
16639
16640        synchronized(this) {
16641            if (values == null && mWindowManager != null) {
16642                // sentinel: fetch the current configuration from the window manager
16643                values = mWindowManager.computeNewConfiguration();
16644            }
16645
16646            if (mWindowManager != null) {
16647                mProcessList.applyDisplaySize(mWindowManager);
16648            }
16649
16650            final long origId = Binder.clearCallingIdentity();
16651            if (values != null) {
16652                Settings.System.clearConfiguration(values);
16653            }
16654            updateConfigurationLocked(values, null, false, false);
16655            Binder.restoreCallingIdentity(origId);
16656        }
16657    }
16658
16659    /**
16660     * Do either or both things: (1) change the current configuration, and (2)
16661     * make sure the given activity is running with the (now) current
16662     * configuration.  Returns true if the activity has been left running, or
16663     * false if <var>starting</var> is being destroyed to match the new
16664     * configuration.
16665     * @param persistent TODO
16666     */
16667    boolean updateConfigurationLocked(Configuration values,
16668            ActivityRecord starting, boolean persistent, boolean initLocale) {
16669        int changes = 0;
16670
16671        if (values != null) {
16672            Configuration newConfig = new Configuration(mConfiguration);
16673            changes = newConfig.updateFrom(values);
16674            if (changes != 0) {
16675                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16676                    Slog.i(TAG, "Updating configuration to: " + values);
16677                }
16678
16679                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16680
16681                if (values.locale != null && !initLocale) {
16682                    saveLocaleLocked(values.locale,
16683                                     !values.locale.equals(mConfiguration.locale),
16684                                     values.userSetLocale);
16685                }
16686
16687                mConfigurationSeq++;
16688                if (mConfigurationSeq <= 0) {
16689                    mConfigurationSeq = 1;
16690                }
16691                newConfig.seq = mConfigurationSeq;
16692                mConfiguration = newConfig;
16693                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16694                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16695                //mUsageStatsService.noteStartConfig(newConfig);
16696
16697                final Configuration configCopy = new Configuration(mConfiguration);
16698
16699                // TODO: If our config changes, should we auto dismiss any currently
16700                // showing dialogs?
16701                mShowDialogs = shouldShowDialogs(newConfig);
16702
16703                AttributeCache ac = AttributeCache.instance();
16704                if (ac != null) {
16705                    ac.updateConfiguration(configCopy);
16706                }
16707
16708                // Make sure all resources in our process are updated
16709                // right now, so that anyone who is going to retrieve
16710                // resource values after we return will be sure to get
16711                // the new ones.  This is especially important during
16712                // boot, where the first config change needs to guarantee
16713                // all resources have that config before following boot
16714                // code is executed.
16715                mSystemThread.applyConfigurationToResources(configCopy);
16716
16717                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16718                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16719                    msg.obj = new Configuration(configCopy);
16720                    mHandler.sendMessage(msg);
16721                }
16722
16723                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16724                    ProcessRecord app = mLruProcesses.get(i);
16725                    try {
16726                        if (app.thread != null) {
16727                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16728                                    + app.processName + " new config " + mConfiguration);
16729                            app.thread.scheduleConfigurationChanged(configCopy);
16730                        }
16731                    } catch (Exception e) {
16732                    }
16733                }
16734                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16735                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16736                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16737                        | Intent.FLAG_RECEIVER_FOREGROUND);
16738                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16739                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16740                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16741                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16742                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16743                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16744                    broadcastIntentLocked(null, null, intent,
16745                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16746                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16747                }
16748            }
16749        }
16750
16751        boolean kept = true;
16752        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16753        // mainStack is null during startup.
16754        if (mainStack != null) {
16755            if (changes != 0 && starting == null) {
16756                // If the configuration changed, and the caller is not already
16757                // in the process of starting an activity, then find the top
16758                // activity to check if its configuration needs to change.
16759                starting = mainStack.topRunningActivityLocked(null);
16760            }
16761
16762            if (starting != null) {
16763                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16764                // And we need to make sure at this point that all other activities
16765                // are made visible with the correct configuration.
16766                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16767            }
16768        }
16769
16770        if (values != null && mWindowManager != null) {
16771            mWindowManager.setNewConfiguration(mConfiguration);
16772        }
16773
16774        return kept;
16775    }
16776
16777    /**
16778     * Decide based on the configuration whether we should shouw the ANR,
16779     * crash, etc dialogs.  The idea is that if there is no affordnace to
16780     * press the on-screen buttons, we shouldn't show the dialog.
16781     *
16782     * A thought: SystemUI might also want to get told about this, the Power
16783     * dialog / global actions also might want different behaviors.
16784     */
16785    private static final boolean shouldShowDialogs(Configuration config) {
16786        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16787                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16788    }
16789
16790    /**
16791     * Save the locale.  You must be inside a synchronized (this) block.
16792     */
16793    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16794        if(isDiff) {
16795            SystemProperties.set("user.language", l.getLanguage());
16796            SystemProperties.set("user.region", l.getCountry());
16797        }
16798
16799        if(isPersist) {
16800            SystemProperties.set("persist.sys.language", l.getLanguage());
16801            SystemProperties.set("persist.sys.country", l.getCountry());
16802            SystemProperties.set("persist.sys.localevar", l.getVariant());
16803
16804            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16805        }
16806    }
16807
16808    @Override
16809    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16810        synchronized (this) {
16811            ActivityRecord srec = ActivityRecord.forToken(token);
16812            if (srec.task != null && srec.task.stack != null) {
16813                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16814            }
16815        }
16816        return false;
16817    }
16818
16819    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16820            Intent resultData) {
16821
16822        synchronized (this) {
16823            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16824            if (stack != null) {
16825                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16826            }
16827            return false;
16828        }
16829    }
16830
16831    public int getLaunchedFromUid(IBinder activityToken) {
16832        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16833        if (srec == null) {
16834            return -1;
16835        }
16836        return srec.launchedFromUid;
16837    }
16838
16839    public String getLaunchedFromPackage(IBinder activityToken) {
16840        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16841        if (srec == null) {
16842            return null;
16843        }
16844        return srec.launchedFromPackage;
16845    }
16846
16847    // =========================================================
16848    // LIFETIME MANAGEMENT
16849    // =========================================================
16850
16851    // Returns which broadcast queue the app is the current [or imminent] receiver
16852    // on, or 'null' if the app is not an active broadcast recipient.
16853    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16854        BroadcastRecord r = app.curReceiver;
16855        if (r != null) {
16856            return r.queue;
16857        }
16858
16859        // It's not the current receiver, but it might be starting up to become one
16860        synchronized (this) {
16861            for (BroadcastQueue queue : mBroadcastQueues) {
16862                r = queue.mPendingBroadcast;
16863                if (r != null && r.curApp == app) {
16864                    // found it; report which queue it's in
16865                    return queue;
16866                }
16867            }
16868        }
16869
16870        return null;
16871    }
16872
16873    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16874            ComponentName targetComponent, String targetProcess) {
16875        if (!mTrackingAssociations) {
16876            return null;
16877        }
16878        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16879                = mAssociations.get(targetUid);
16880        if (components == null) {
16881            components = new ArrayMap<>();
16882            mAssociations.put(targetUid, components);
16883        }
16884        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16885        if (sourceUids == null) {
16886            sourceUids = new SparseArray<>();
16887            components.put(targetComponent, sourceUids);
16888        }
16889        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16890        if (sourceProcesses == null) {
16891            sourceProcesses = new ArrayMap<>();
16892            sourceUids.put(sourceUid, sourceProcesses);
16893        }
16894        Association ass = sourceProcesses.get(sourceProcess);
16895        if (ass == null) {
16896            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16897                    targetProcess);
16898            sourceProcesses.put(sourceProcess, ass);
16899        }
16900        ass.mCount++;
16901        ass.mNesting++;
16902        if (ass.mNesting == 1) {
16903            ass.mStartTime = SystemClock.uptimeMillis();
16904        }
16905        return ass;
16906    }
16907
16908    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16909            ComponentName targetComponent) {
16910        if (!mTrackingAssociations) {
16911            return;
16912        }
16913        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16914                = mAssociations.get(targetUid);
16915        if (components == null) {
16916            return;
16917        }
16918        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16919        if (sourceUids == null) {
16920            return;
16921        }
16922        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16923        if (sourceProcesses == null) {
16924            return;
16925        }
16926        Association ass = sourceProcesses.get(sourceProcess);
16927        if (ass == null || ass.mNesting <= 0) {
16928            return;
16929        }
16930        ass.mNesting--;
16931        if (ass.mNesting == 0) {
16932            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16933        }
16934    }
16935
16936    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16937            boolean doingAll, long now) {
16938        if (mAdjSeq == app.adjSeq) {
16939            // This adjustment has already been computed.
16940            return app.curRawAdj;
16941        }
16942
16943        if (app.thread == null) {
16944            app.adjSeq = mAdjSeq;
16945            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16946            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16947            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16948        }
16949
16950        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16951        app.adjSource = null;
16952        app.adjTarget = null;
16953        app.empty = false;
16954        app.cached = false;
16955
16956        final int activitiesSize = app.activities.size();
16957
16958        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16959            // The max adjustment doesn't allow this app to be anything
16960            // below foreground, so it is not worth doing work for it.
16961            app.adjType = "fixed";
16962            app.adjSeq = mAdjSeq;
16963            app.curRawAdj = app.maxAdj;
16964            app.foregroundActivities = false;
16965            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16966            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16967            // System processes can do UI, and when they do we want to have
16968            // them trim their memory after the user leaves the UI.  To
16969            // facilitate this, here we need to determine whether or not it
16970            // is currently showing UI.
16971            app.systemNoUi = true;
16972            if (app == TOP_APP) {
16973                app.systemNoUi = false;
16974            } else if (activitiesSize > 0) {
16975                for (int j = 0; j < activitiesSize; j++) {
16976                    final ActivityRecord r = app.activities.get(j);
16977                    if (r.visible) {
16978                        app.systemNoUi = false;
16979                    }
16980                }
16981            }
16982            if (!app.systemNoUi) {
16983                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16984            }
16985            return (app.curAdj=app.maxAdj);
16986        }
16987
16988        app.systemNoUi = false;
16989
16990        // Determine the importance of the process, starting with most
16991        // important to least, and assign an appropriate OOM adjustment.
16992        int adj;
16993        int schedGroup;
16994        int procState;
16995        boolean foregroundActivities = false;
16996        BroadcastQueue queue;
16997        if (app == TOP_APP) {
16998            // The last app on the list is the foreground app.
16999            adj = ProcessList.FOREGROUND_APP_ADJ;
17000            schedGroup = Process.THREAD_GROUP_DEFAULT;
17001            app.adjType = "top-activity";
17002            foregroundActivities = true;
17003            procState = ActivityManager.PROCESS_STATE_TOP;
17004        } else if (app.instrumentationClass != null) {
17005            // Don't want to kill running instrumentation.
17006            adj = ProcessList.FOREGROUND_APP_ADJ;
17007            schedGroup = Process.THREAD_GROUP_DEFAULT;
17008            app.adjType = "instrumentation";
17009            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17010        } else if ((queue = isReceivingBroadcast(app)) != null) {
17011            // An app that is currently receiving a broadcast also
17012            // counts as being in the foreground for OOM killer purposes.
17013            // It's placed in a sched group based on the nature of the
17014            // broadcast as reflected by which queue it's active in.
17015            adj = ProcessList.FOREGROUND_APP_ADJ;
17016            schedGroup = (queue == mFgBroadcastQueue)
17017                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17018            app.adjType = "broadcast";
17019            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17020        } else if (app.executingServices.size() > 0) {
17021            // An app that is currently executing a service callback also
17022            // counts as being in the foreground.
17023            adj = ProcessList.FOREGROUND_APP_ADJ;
17024            schedGroup = app.execServicesFg ?
17025                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17026            app.adjType = "exec-service";
17027            procState = ActivityManager.PROCESS_STATE_SERVICE;
17028            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17029        } else {
17030            // As far as we know the process is empty.  We may change our mind later.
17031            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17032            // At this point we don't actually know the adjustment.  Use the cached adj
17033            // value that the caller wants us to.
17034            adj = cachedAdj;
17035            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17036            app.cached = true;
17037            app.empty = true;
17038            app.adjType = "cch-empty";
17039        }
17040
17041        // Examine all activities if not already foreground.
17042        if (!foregroundActivities && activitiesSize > 0) {
17043            for (int j = 0; j < activitiesSize; j++) {
17044                final ActivityRecord r = app.activities.get(j);
17045                if (r.app != app) {
17046                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17047                            + app + "?!?");
17048                    continue;
17049                }
17050                if (r.visible) {
17051                    // App has a visible activity; only upgrade adjustment.
17052                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17053                        adj = ProcessList.VISIBLE_APP_ADJ;
17054                        app.adjType = "visible";
17055                    }
17056                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17057                        procState = ActivityManager.PROCESS_STATE_TOP;
17058                    }
17059                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17060                    app.cached = false;
17061                    app.empty = false;
17062                    foregroundActivities = true;
17063                    break;
17064                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17065                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17066                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17067                        app.adjType = "pausing";
17068                    }
17069                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17070                        procState = ActivityManager.PROCESS_STATE_TOP;
17071                    }
17072                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17073                    app.cached = false;
17074                    app.empty = false;
17075                    foregroundActivities = true;
17076                } else if (r.state == ActivityState.STOPPING) {
17077                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17078                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17079                        app.adjType = "stopping";
17080                    }
17081                    // For the process state, we will at this point consider the
17082                    // process to be cached.  It will be cached either as an activity
17083                    // or empty depending on whether the activity is finishing.  We do
17084                    // this so that we can treat the process as cached for purposes of
17085                    // memory trimming (determing current memory level, trim command to
17086                    // send to process) since there can be an arbitrary number of stopping
17087                    // processes and they should soon all go into the cached state.
17088                    if (!r.finishing) {
17089                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17090                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17091                        }
17092                    }
17093                    app.cached = false;
17094                    app.empty = false;
17095                    foregroundActivities = true;
17096                } else {
17097                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17098                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17099                        app.adjType = "cch-act";
17100                    }
17101                }
17102            }
17103        }
17104
17105        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17106            if (app.foregroundServices) {
17107                // The user is aware of this app, so make it visible.
17108                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17109                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17110                app.cached = false;
17111                app.adjType = "fg-service";
17112                schedGroup = Process.THREAD_GROUP_DEFAULT;
17113            } else if (app.forcingToForeground != null) {
17114                // The user is aware of this app, so make it visible.
17115                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17116                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17117                app.cached = false;
17118                app.adjType = "force-fg";
17119                app.adjSource = app.forcingToForeground;
17120                schedGroup = Process.THREAD_GROUP_DEFAULT;
17121            }
17122        }
17123
17124        if (app == mHeavyWeightProcess) {
17125            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17126                // We don't want to kill the current heavy-weight process.
17127                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17128                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17129                app.cached = false;
17130                app.adjType = "heavy";
17131            }
17132            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17133                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17134            }
17135        }
17136
17137        if (app == mHomeProcess) {
17138            if (adj > ProcessList.HOME_APP_ADJ) {
17139                // This process is hosting what we currently consider to be the
17140                // home app, so we don't want to let it go into the background.
17141                adj = ProcessList.HOME_APP_ADJ;
17142                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17143                app.cached = false;
17144                app.adjType = "home";
17145            }
17146            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17147                procState = ActivityManager.PROCESS_STATE_HOME;
17148            }
17149        }
17150
17151        if (app == mPreviousProcess && app.activities.size() > 0) {
17152            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17153                // This was the previous process that showed UI to the user.
17154                // We want to try to keep it around more aggressively, to give
17155                // a good experience around switching between two apps.
17156                adj = ProcessList.PREVIOUS_APP_ADJ;
17157                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17158                app.cached = false;
17159                app.adjType = "previous";
17160            }
17161            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17162                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17163            }
17164        }
17165
17166        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17167                + " reason=" + app.adjType);
17168
17169        // By default, we use the computed adjustment.  It may be changed if
17170        // there are applications dependent on our services or providers, but
17171        // this gives us a baseline and makes sure we don't get into an
17172        // infinite recursion.
17173        app.adjSeq = mAdjSeq;
17174        app.curRawAdj = adj;
17175        app.hasStartedServices = false;
17176
17177        if (mBackupTarget != null && app == mBackupTarget.app) {
17178            // If possible we want to avoid killing apps while they're being backed up
17179            if (adj > ProcessList.BACKUP_APP_ADJ) {
17180                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17181                adj = ProcessList.BACKUP_APP_ADJ;
17182                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17183                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17184                }
17185                app.adjType = "backup";
17186                app.cached = false;
17187            }
17188            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17189                procState = ActivityManager.PROCESS_STATE_BACKUP;
17190            }
17191        }
17192
17193        boolean mayBeTop = false;
17194
17195        for (int is = app.services.size()-1;
17196                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17197                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17198                        || procState > ActivityManager.PROCESS_STATE_TOP);
17199                is--) {
17200            ServiceRecord s = app.services.valueAt(is);
17201            if (s.startRequested) {
17202                app.hasStartedServices = true;
17203                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17204                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17205                }
17206                if (app.hasShownUi && app != mHomeProcess) {
17207                    // If this process has shown some UI, let it immediately
17208                    // go to the LRU list because it may be pretty heavy with
17209                    // UI stuff.  We'll tag it with a label just to help
17210                    // debug and understand what is going on.
17211                    if (adj > ProcessList.SERVICE_ADJ) {
17212                        app.adjType = "cch-started-ui-services";
17213                    }
17214                } else {
17215                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17216                        // This service has seen some activity within
17217                        // recent memory, so we will keep its process ahead
17218                        // of the background processes.
17219                        if (adj > ProcessList.SERVICE_ADJ) {
17220                            adj = ProcessList.SERVICE_ADJ;
17221                            app.adjType = "started-services";
17222                            app.cached = false;
17223                        }
17224                    }
17225                    // If we have let the service slide into the background
17226                    // state, still have some text describing what it is doing
17227                    // even though the service no longer has an impact.
17228                    if (adj > ProcessList.SERVICE_ADJ) {
17229                        app.adjType = "cch-started-services";
17230                    }
17231                }
17232            }
17233            for (int conni = s.connections.size()-1;
17234                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17235                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17236                            || procState > ActivityManager.PROCESS_STATE_TOP);
17237                    conni--) {
17238                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17239                for (int i = 0;
17240                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17241                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17242                                || procState > ActivityManager.PROCESS_STATE_TOP);
17243                        i++) {
17244                    // XXX should compute this based on the max of
17245                    // all connected clients.
17246                    ConnectionRecord cr = clist.get(i);
17247                    if (cr.binding.client == app) {
17248                        // Binding to ourself is not interesting.
17249                        continue;
17250                    }
17251                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17252                        ProcessRecord client = cr.binding.client;
17253                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17254                                TOP_APP, doingAll, now);
17255                        int clientProcState = client.curProcState;
17256                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17257                            // If the other app is cached for any reason, for purposes here
17258                            // we are going to consider it empty.  The specific cached state
17259                            // doesn't propagate except under certain conditions.
17260                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17261                        }
17262                        String adjType = null;
17263                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17264                            // Not doing bind OOM management, so treat
17265                            // this guy more like a started service.
17266                            if (app.hasShownUi && app != mHomeProcess) {
17267                                // If this process has shown some UI, let it immediately
17268                                // go to the LRU list because it may be pretty heavy with
17269                                // UI stuff.  We'll tag it with a label just to help
17270                                // debug and understand what is going on.
17271                                if (adj > clientAdj) {
17272                                    adjType = "cch-bound-ui-services";
17273                                }
17274                                app.cached = false;
17275                                clientAdj = adj;
17276                                clientProcState = procState;
17277                            } else {
17278                                if (now >= (s.lastActivity
17279                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17280                                    // This service has not seen activity within
17281                                    // recent memory, so allow it to drop to the
17282                                    // LRU list if there is no other reason to keep
17283                                    // it around.  We'll also tag it with a label just
17284                                    // to help debug and undertand what is going on.
17285                                    if (adj > clientAdj) {
17286                                        adjType = "cch-bound-services";
17287                                    }
17288                                    clientAdj = adj;
17289                                }
17290                            }
17291                        }
17292                        if (adj > clientAdj) {
17293                            // If this process has recently shown UI, and
17294                            // the process that is binding to it is less
17295                            // important than being visible, then we don't
17296                            // care about the binding as much as we care
17297                            // about letting this process get into the LRU
17298                            // list to be killed and restarted if needed for
17299                            // memory.
17300                            if (app.hasShownUi && app != mHomeProcess
17301                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17302                                adjType = "cch-bound-ui-services";
17303                            } else {
17304                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17305                                        |Context.BIND_IMPORTANT)) != 0) {
17306                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17307                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17308                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17309                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17310                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17311                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17312                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17313                                    adj = clientAdj;
17314                                } else {
17315                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17316                                        adj = ProcessList.VISIBLE_APP_ADJ;
17317                                    }
17318                                }
17319                                if (!client.cached) {
17320                                    app.cached = false;
17321                                }
17322                                adjType = "service";
17323                            }
17324                        }
17325                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17326                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17327                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17328                            }
17329                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17330                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17331                                    // Special handling of clients who are in the top state.
17332                                    // We *may* want to consider this process to be in the
17333                                    // top state as well, but only if there is not another
17334                                    // reason for it to be running.  Being on the top is a
17335                                    // special state, meaning you are specifically running
17336                                    // for the current top app.  If the process is already
17337                                    // running in the background for some other reason, it
17338                                    // is more important to continue considering it to be
17339                                    // in the background state.
17340                                    mayBeTop = true;
17341                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17342                                } else {
17343                                    // Special handling for above-top states (persistent
17344                                    // processes).  These should not bring the current process
17345                                    // into the top state, since they are not on top.  Instead
17346                                    // give them the best state after that.
17347                                    clientProcState =
17348                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17349                                }
17350                            }
17351                        } else {
17352                            if (clientProcState <
17353                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17354                                clientProcState =
17355                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17356                            }
17357                        }
17358                        if (procState > clientProcState) {
17359                            procState = clientProcState;
17360                        }
17361                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17362                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17363                            app.pendingUiClean = true;
17364                        }
17365                        if (adjType != null) {
17366                            app.adjType = adjType;
17367                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17368                                    .REASON_SERVICE_IN_USE;
17369                            app.adjSource = cr.binding.client;
17370                            app.adjSourceProcState = clientProcState;
17371                            app.adjTarget = s.name;
17372                        }
17373                    }
17374                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17375                        app.treatLikeActivity = true;
17376                    }
17377                    final ActivityRecord a = cr.activity;
17378                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17379                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17380                                (a.visible || a.state == ActivityState.RESUMED
17381                                 || a.state == ActivityState.PAUSING)) {
17382                            adj = ProcessList.FOREGROUND_APP_ADJ;
17383                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17384                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17385                            }
17386                            app.cached = false;
17387                            app.adjType = "service";
17388                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17389                                    .REASON_SERVICE_IN_USE;
17390                            app.adjSource = a;
17391                            app.adjSourceProcState = procState;
17392                            app.adjTarget = s.name;
17393                        }
17394                    }
17395                }
17396            }
17397        }
17398
17399        for (int provi = app.pubProviders.size()-1;
17400                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17401                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17402                        || procState > ActivityManager.PROCESS_STATE_TOP);
17403                provi--) {
17404            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17405            for (int i = cpr.connections.size()-1;
17406                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17407                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17408                            || procState > ActivityManager.PROCESS_STATE_TOP);
17409                    i--) {
17410                ContentProviderConnection conn = cpr.connections.get(i);
17411                ProcessRecord client = conn.client;
17412                if (client == app) {
17413                    // Being our own client is not interesting.
17414                    continue;
17415                }
17416                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17417                int clientProcState = client.curProcState;
17418                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17419                    // If the other app is cached for any reason, for purposes here
17420                    // we are going to consider it empty.
17421                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17422                }
17423                if (adj > clientAdj) {
17424                    if (app.hasShownUi && app != mHomeProcess
17425                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17426                        app.adjType = "cch-ui-provider";
17427                    } else {
17428                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17429                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17430                        app.adjType = "provider";
17431                    }
17432                    app.cached &= client.cached;
17433                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17434                            .REASON_PROVIDER_IN_USE;
17435                    app.adjSource = client;
17436                    app.adjSourceProcState = clientProcState;
17437                    app.adjTarget = cpr.name;
17438                }
17439                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17440                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17441                        // Special handling of clients who are in the top state.
17442                        // We *may* want to consider this process to be in the
17443                        // top state as well, but only if there is not another
17444                        // reason for it to be running.  Being on the top is a
17445                        // special state, meaning you are specifically running
17446                        // for the current top app.  If the process is already
17447                        // running in the background for some other reason, it
17448                        // is more important to continue considering it to be
17449                        // in the background state.
17450                        mayBeTop = true;
17451                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17452                    } else {
17453                        // Special handling for above-top states (persistent
17454                        // processes).  These should not bring the current process
17455                        // into the top state, since they are not on top.  Instead
17456                        // give them the best state after that.
17457                        clientProcState =
17458                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17459                    }
17460                }
17461                if (procState > clientProcState) {
17462                    procState = clientProcState;
17463                }
17464                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17465                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17466                }
17467            }
17468            // If the provider has external (non-framework) process
17469            // dependencies, ensure that its adjustment is at least
17470            // FOREGROUND_APP_ADJ.
17471            if (cpr.hasExternalProcessHandles()) {
17472                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17473                    adj = ProcessList.FOREGROUND_APP_ADJ;
17474                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17475                    app.cached = false;
17476                    app.adjType = "provider";
17477                    app.adjTarget = cpr.name;
17478                }
17479                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17480                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17481                }
17482            }
17483        }
17484
17485        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17486            // A client of one of our services or providers is in the top state.  We
17487            // *may* want to be in the top state, but not if we are already running in
17488            // the background for some other reason.  For the decision here, we are going
17489            // to pick out a few specific states that we want to remain in when a client
17490            // is top (states that tend to be longer-term) and otherwise allow it to go
17491            // to the top state.
17492            switch (procState) {
17493                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17494                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17495                case ActivityManager.PROCESS_STATE_SERVICE:
17496                    // These all are longer-term states, so pull them up to the top
17497                    // of the background states, but not all the way to the top state.
17498                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17499                    break;
17500                default:
17501                    // Otherwise, top is a better choice, so take it.
17502                    procState = ActivityManager.PROCESS_STATE_TOP;
17503                    break;
17504            }
17505        }
17506
17507        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17508            if (app.hasClientActivities) {
17509                // This is a cached process, but with client activities.  Mark it so.
17510                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17511                app.adjType = "cch-client-act";
17512            } else if (app.treatLikeActivity) {
17513                // This is a cached process, but somebody wants us to treat it like it has
17514                // an activity, okay!
17515                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17516                app.adjType = "cch-as-act";
17517            }
17518        }
17519
17520        if (adj == ProcessList.SERVICE_ADJ) {
17521            if (doingAll) {
17522                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17523                mNewNumServiceProcs++;
17524                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17525                if (!app.serviceb) {
17526                    // This service isn't far enough down on the LRU list to
17527                    // normally be a B service, but if we are low on RAM and it
17528                    // is large we want to force it down since we would prefer to
17529                    // keep launcher over it.
17530                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17531                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17532                        app.serviceHighRam = true;
17533                        app.serviceb = true;
17534                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17535                    } else {
17536                        mNewNumAServiceProcs++;
17537                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17538                    }
17539                } else {
17540                    app.serviceHighRam = false;
17541                }
17542            }
17543            if (app.serviceb) {
17544                adj = ProcessList.SERVICE_B_ADJ;
17545            }
17546        }
17547
17548        app.curRawAdj = adj;
17549
17550        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17551        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17552        if (adj > app.maxAdj) {
17553            adj = app.maxAdj;
17554            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17555                schedGroup = Process.THREAD_GROUP_DEFAULT;
17556            }
17557        }
17558
17559        // Do final modification to adj.  Everything we do between here and applying
17560        // the final setAdj must be done in this function, because we will also use
17561        // it when computing the final cached adj later.  Note that we don't need to
17562        // worry about this for max adj above, since max adj will always be used to
17563        // keep it out of the cached vaues.
17564        app.curAdj = app.modifyRawOomAdj(adj);
17565        app.curSchedGroup = schedGroup;
17566        app.curProcState = procState;
17567        app.foregroundActivities = foregroundActivities;
17568
17569        return app.curRawAdj;
17570    }
17571
17572    /**
17573     * Record new PSS sample for a process.
17574     */
17575    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17576        proc.lastPssTime = now;
17577        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17578        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17579                + ": " + pss + " lastPss=" + proc.lastPss
17580                + " state=" + ProcessList.makeProcStateString(procState));
17581        if (proc.initialIdlePss == 0) {
17582            proc.initialIdlePss = pss;
17583        }
17584        proc.lastPss = pss;
17585        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17586            proc.lastCachedPss = pss;
17587        }
17588    }
17589
17590    /**
17591     * Schedule PSS collection of a process.
17592     */
17593    void requestPssLocked(ProcessRecord proc, int procState) {
17594        if (mPendingPssProcesses.contains(proc)) {
17595            return;
17596        }
17597        if (mPendingPssProcesses.size() == 0) {
17598            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17599        }
17600        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17601        proc.pssProcState = procState;
17602        mPendingPssProcesses.add(proc);
17603    }
17604
17605    /**
17606     * Schedule PSS collection of all processes.
17607     */
17608    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17609        if (!always) {
17610            if (now < (mLastFullPssTime +
17611                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17612                return;
17613            }
17614        }
17615        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17616        mLastFullPssTime = now;
17617        mFullPssPending = true;
17618        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17619        mPendingPssProcesses.clear();
17620        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17621            ProcessRecord app = mLruProcesses.get(i);
17622            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17623                app.pssProcState = app.setProcState;
17624                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17625                        mTestPssMode, isSleeping(), now);
17626                mPendingPssProcesses.add(app);
17627            }
17628        }
17629        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17630    }
17631
17632    public void setTestPssMode(boolean enabled) {
17633        synchronized (this) {
17634            mTestPssMode = enabled;
17635            if (enabled) {
17636                // Whenever we enable the mode, we want to take a snapshot all of current
17637                // process mem use.
17638                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17639            }
17640        }
17641    }
17642
17643    /**
17644     * Ask a given process to GC right now.
17645     */
17646    final void performAppGcLocked(ProcessRecord app) {
17647        try {
17648            app.lastRequestedGc = SystemClock.uptimeMillis();
17649            if (app.thread != null) {
17650                if (app.reportLowMemory) {
17651                    app.reportLowMemory = false;
17652                    app.thread.scheduleLowMemory();
17653                } else {
17654                    app.thread.processInBackground();
17655                }
17656            }
17657        } catch (Exception e) {
17658            // whatever.
17659        }
17660    }
17661
17662    /**
17663     * Returns true if things are idle enough to perform GCs.
17664     */
17665    private final boolean canGcNowLocked() {
17666        boolean processingBroadcasts = false;
17667        for (BroadcastQueue q : mBroadcastQueues) {
17668            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17669                processingBroadcasts = true;
17670            }
17671        }
17672        return !processingBroadcasts
17673                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17674    }
17675
17676    /**
17677     * Perform GCs on all processes that are waiting for it, but only
17678     * if things are idle.
17679     */
17680    final void performAppGcsLocked() {
17681        final int N = mProcessesToGc.size();
17682        if (N <= 0) {
17683            return;
17684        }
17685        if (canGcNowLocked()) {
17686            while (mProcessesToGc.size() > 0) {
17687                ProcessRecord proc = mProcessesToGc.remove(0);
17688                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17689                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17690                            <= SystemClock.uptimeMillis()) {
17691                        // To avoid spamming the system, we will GC processes one
17692                        // at a time, waiting a few seconds between each.
17693                        performAppGcLocked(proc);
17694                        scheduleAppGcsLocked();
17695                        return;
17696                    } else {
17697                        // It hasn't been long enough since we last GCed this
17698                        // process...  put it in the list to wait for its time.
17699                        addProcessToGcListLocked(proc);
17700                        break;
17701                    }
17702                }
17703            }
17704
17705            scheduleAppGcsLocked();
17706        }
17707    }
17708
17709    /**
17710     * If all looks good, perform GCs on all processes waiting for them.
17711     */
17712    final void performAppGcsIfAppropriateLocked() {
17713        if (canGcNowLocked()) {
17714            performAppGcsLocked();
17715            return;
17716        }
17717        // Still not idle, wait some more.
17718        scheduleAppGcsLocked();
17719    }
17720
17721    /**
17722     * Schedule the execution of all pending app GCs.
17723     */
17724    final void scheduleAppGcsLocked() {
17725        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17726
17727        if (mProcessesToGc.size() > 0) {
17728            // Schedule a GC for the time to the next process.
17729            ProcessRecord proc = mProcessesToGc.get(0);
17730            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17731
17732            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17733            long now = SystemClock.uptimeMillis();
17734            if (when < (now+GC_TIMEOUT)) {
17735                when = now + GC_TIMEOUT;
17736            }
17737            mHandler.sendMessageAtTime(msg, when);
17738        }
17739    }
17740
17741    /**
17742     * Add a process to the array of processes waiting to be GCed.  Keeps the
17743     * list in sorted order by the last GC time.  The process can't already be
17744     * on the list.
17745     */
17746    final void addProcessToGcListLocked(ProcessRecord proc) {
17747        boolean added = false;
17748        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17749            if (mProcessesToGc.get(i).lastRequestedGc <
17750                    proc.lastRequestedGc) {
17751                added = true;
17752                mProcessesToGc.add(i+1, proc);
17753                break;
17754            }
17755        }
17756        if (!added) {
17757            mProcessesToGc.add(0, proc);
17758        }
17759    }
17760
17761    /**
17762     * Set up to ask a process to GC itself.  This will either do it
17763     * immediately, or put it on the list of processes to gc the next
17764     * time things are idle.
17765     */
17766    final void scheduleAppGcLocked(ProcessRecord app) {
17767        long now = SystemClock.uptimeMillis();
17768        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17769            return;
17770        }
17771        if (!mProcessesToGc.contains(app)) {
17772            addProcessToGcListLocked(app);
17773            scheduleAppGcsLocked();
17774        }
17775    }
17776
17777    final void checkExcessivePowerUsageLocked(boolean doKills) {
17778        updateCpuStatsNow();
17779
17780        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17781        boolean doWakeKills = doKills;
17782        boolean doCpuKills = doKills;
17783        if (mLastPowerCheckRealtime == 0) {
17784            doWakeKills = false;
17785        }
17786        if (mLastPowerCheckUptime == 0) {
17787            doCpuKills = false;
17788        }
17789        if (stats.isScreenOn()) {
17790            doWakeKills = false;
17791        }
17792        final long curRealtime = SystemClock.elapsedRealtime();
17793        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17794        final long curUptime = SystemClock.uptimeMillis();
17795        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17796        mLastPowerCheckRealtime = curRealtime;
17797        mLastPowerCheckUptime = curUptime;
17798        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17799            doWakeKills = false;
17800        }
17801        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17802            doCpuKills = false;
17803        }
17804        int i = mLruProcesses.size();
17805        while (i > 0) {
17806            i--;
17807            ProcessRecord app = mLruProcesses.get(i);
17808            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17809                long wtime;
17810                synchronized (stats) {
17811                    wtime = stats.getProcessWakeTime(app.info.uid,
17812                            app.pid, curRealtime);
17813                }
17814                long wtimeUsed = wtime - app.lastWakeTime;
17815                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17816                if (DEBUG_POWER) {
17817                    StringBuilder sb = new StringBuilder(128);
17818                    sb.append("Wake for ");
17819                    app.toShortString(sb);
17820                    sb.append(": over ");
17821                    TimeUtils.formatDuration(realtimeSince, sb);
17822                    sb.append(" used ");
17823                    TimeUtils.formatDuration(wtimeUsed, sb);
17824                    sb.append(" (");
17825                    sb.append((wtimeUsed*100)/realtimeSince);
17826                    sb.append("%)");
17827                    Slog.i(TAG, sb.toString());
17828                    sb.setLength(0);
17829                    sb.append("CPU for ");
17830                    app.toShortString(sb);
17831                    sb.append(": over ");
17832                    TimeUtils.formatDuration(uptimeSince, sb);
17833                    sb.append(" used ");
17834                    TimeUtils.formatDuration(cputimeUsed, sb);
17835                    sb.append(" (");
17836                    sb.append((cputimeUsed*100)/uptimeSince);
17837                    sb.append("%)");
17838                    Slog.i(TAG, sb.toString());
17839                }
17840                // If a process has held a wake lock for more
17841                // than 50% of the time during this period,
17842                // that sounds bad.  Kill!
17843                if (doWakeKills && realtimeSince > 0
17844                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17845                    synchronized (stats) {
17846                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17847                                realtimeSince, wtimeUsed);
17848                    }
17849                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17850                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17851                } else if (doCpuKills && uptimeSince > 0
17852                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17853                    synchronized (stats) {
17854                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17855                                uptimeSince, cputimeUsed);
17856                    }
17857                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17858                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17859                } else {
17860                    app.lastWakeTime = wtime;
17861                    app.lastCpuTime = app.curCpuTime;
17862                }
17863            }
17864        }
17865    }
17866
17867    private final boolean applyOomAdjLocked(ProcessRecord app,
17868            ProcessRecord TOP_APP, boolean doingAll, long now) {
17869        boolean success = true;
17870
17871        if (app.curRawAdj != app.setRawAdj) {
17872            app.setRawAdj = app.curRawAdj;
17873        }
17874
17875        int changes = 0;
17876
17877        if (app.curAdj != app.setAdj) {
17878            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17879            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17880                TAG, "Set " + app.pid + " " + app.processName +
17881                " adj " + app.curAdj + ": " + app.adjType);
17882            app.setAdj = app.curAdj;
17883        }
17884
17885        if (app.setSchedGroup != app.curSchedGroup) {
17886            app.setSchedGroup = app.curSchedGroup;
17887            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17888                    "Setting process group of " + app.processName
17889                    + " to " + app.curSchedGroup);
17890            if (app.waitingToKill != null &&
17891                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17892                app.kill(app.waitingToKill, true);
17893                success = false;
17894            } else {
17895                if (true) {
17896                    long oldId = Binder.clearCallingIdentity();
17897                    try {
17898                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17899                    } catch (Exception e) {
17900                        Slog.w(TAG, "Failed setting process group of " + app.pid
17901                                + " to " + app.curSchedGroup);
17902                        e.printStackTrace();
17903                    } finally {
17904                        Binder.restoreCallingIdentity(oldId);
17905                    }
17906                } else {
17907                    if (app.thread != null) {
17908                        try {
17909                            app.thread.setSchedulingGroup(app.curSchedGroup);
17910                        } catch (RemoteException e) {
17911                        }
17912                    }
17913                }
17914                Process.setSwappiness(app.pid,
17915                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17916            }
17917        }
17918        if (app.repForegroundActivities != app.foregroundActivities) {
17919            app.repForegroundActivities = app.foregroundActivities;
17920            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17921        }
17922        if (app.repProcState != app.curProcState) {
17923            app.repProcState = app.curProcState;
17924            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17925            if (app.thread != null) {
17926                try {
17927                    if (false) {
17928                        //RuntimeException h = new RuntimeException("here");
17929                        Slog.i(TAG, "Sending new process state " + app.repProcState
17930                                + " to " + app /*, h*/);
17931                    }
17932                    app.thread.setProcessState(app.repProcState);
17933                } catch (RemoteException e) {
17934                }
17935            }
17936        }
17937        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17938                app.setProcState)) {
17939            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17940                // Experimental code to more aggressively collect pss while
17941                // running test...  the problem is that this tends to collect
17942                // the data right when a process is transitioning between process
17943                // states, which well tend to give noisy data.
17944                long start = SystemClock.uptimeMillis();
17945                long pss = Debug.getPss(app.pid, mTmpLong, null);
17946                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17947                mPendingPssProcesses.remove(app);
17948                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17949                        + " to " + app.curProcState + ": "
17950                        + (SystemClock.uptimeMillis()-start) + "ms");
17951            }
17952            app.lastStateTime = now;
17953            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17954                    mTestPssMode, isSleeping(), now);
17955            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17956                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17957                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17958                    + (app.nextPssTime-now) + ": " + app);
17959        } else {
17960            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17961                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17962                    mTestPssMode)))) {
17963                requestPssLocked(app, app.setProcState);
17964                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17965                        mTestPssMode, isSleeping(), now);
17966            } else if (false && DEBUG_PSS) {
17967                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17968            }
17969        }
17970        if (app.setProcState != app.curProcState) {
17971            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17972                    "Proc state change of " + app.processName
17973                    + " to " + app.curProcState);
17974            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17975            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17976            if (setImportant && !curImportant) {
17977                // This app is no longer something we consider important enough to allow to
17978                // use arbitrary amounts of battery power.  Note
17979                // its current wake lock time to later know to kill it if
17980                // it is not behaving well.
17981                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17982                synchronized (stats) {
17983                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17984                            app.pid, SystemClock.elapsedRealtime());
17985                }
17986                app.lastCpuTime = app.curCpuTime;
17987
17988            }
17989            app.setProcState = app.curProcState;
17990            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17991                app.notCachedSinceIdle = false;
17992            }
17993            if (!doingAll) {
17994                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17995            } else {
17996                app.procStateChanged = true;
17997            }
17998        }
17999
18000        if (changes != 0) {
18001            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18002            int i = mPendingProcessChanges.size()-1;
18003            ProcessChangeItem item = null;
18004            while (i >= 0) {
18005                item = mPendingProcessChanges.get(i);
18006                if (item.pid == app.pid) {
18007                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18008                    break;
18009                }
18010                i--;
18011            }
18012            if (i < 0) {
18013                // No existing item in pending changes; need a new one.
18014                final int NA = mAvailProcessChanges.size();
18015                if (NA > 0) {
18016                    item = mAvailProcessChanges.remove(NA-1);
18017                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18018                } else {
18019                    item = new ProcessChangeItem();
18020                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18021                }
18022                item.changes = 0;
18023                item.pid = app.pid;
18024                item.uid = app.info.uid;
18025                if (mPendingProcessChanges.size() == 0) {
18026                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18027                            "*** Enqueueing dispatch processes changed!");
18028                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18029                }
18030                mPendingProcessChanges.add(item);
18031            }
18032            item.changes |= changes;
18033            item.processState = app.repProcState;
18034            item.foregroundActivities = app.repForegroundActivities;
18035            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18036                    + Integer.toHexString(System.identityHashCode(item))
18037                    + " " + app.toShortString() + ": changes=" + item.changes
18038                    + " procState=" + item.processState
18039                    + " foreground=" + item.foregroundActivities
18040                    + " type=" + app.adjType + " source=" + app.adjSource
18041                    + " target=" + app.adjTarget);
18042        }
18043
18044        return success;
18045    }
18046
18047    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18048        if (proc.thread != null) {
18049            if (proc.baseProcessTracker != null) {
18050                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18051            }
18052            if (proc.repProcState >= 0) {
18053                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18054                        proc.repProcState);
18055            }
18056        }
18057    }
18058
18059    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18060            ProcessRecord TOP_APP, boolean doingAll, long now) {
18061        if (app.thread == null) {
18062            return false;
18063        }
18064
18065        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18066
18067        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18068    }
18069
18070    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18071            boolean oomAdj) {
18072        if (isForeground != proc.foregroundServices) {
18073            proc.foregroundServices = isForeground;
18074            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18075                    proc.info.uid);
18076            if (isForeground) {
18077                if (curProcs == null) {
18078                    curProcs = new ArrayList<ProcessRecord>();
18079                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18080                }
18081                if (!curProcs.contains(proc)) {
18082                    curProcs.add(proc);
18083                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18084                            proc.info.packageName, proc.info.uid);
18085                }
18086            } else {
18087                if (curProcs != null) {
18088                    if (curProcs.remove(proc)) {
18089                        mBatteryStatsService.noteEvent(
18090                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18091                                proc.info.packageName, proc.info.uid);
18092                        if (curProcs.size() <= 0) {
18093                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18094                        }
18095                    }
18096                }
18097            }
18098            if (oomAdj) {
18099                updateOomAdjLocked();
18100            }
18101        }
18102    }
18103
18104    private final ActivityRecord resumedAppLocked() {
18105        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18106        String pkg;
18107        int uid;
18108        if (act != null) {
18109            pkg = act.packageName;
18110            uid = act.info.applicationInfo.uid;
18111        } else {
18112            pkg = null;
18113            uid = -1;
18114        }
18115        // Has the UID or resumed package name changed?
18116        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18117                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18118            if (mCurResumedPackage != null) {
18119                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18120                        mCurResumedPackage, mCurResumedUid);
18121            }
18122            mCurResumedPackage = pkg;
18123            mCurResumedUid = uid;
18124            if (mCurResumedPackage != null) {
18125                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18126                        mCurResumedPackage, mCurResumedUid);
18127            }
18128        }
18129        return act;
18130    }
18131
18132    final boolean updateOomAdjLocked(ProcessRecord app) {
18133        final ActivityRecord TOP_ACT = resumedAppLocked();
18134        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18135        final boolean wasCached = app.cached;
18136
18137        mAdjSeq++;
18138
18139        // This is the desired cached adjusment we want to tell it to use.
18140        // If our app is currently cached, we know it, and that is it.  Otherwise,
18141        // we don't know it yet, and it needs to now be cached we will then
18142        // need to do a complete oom adj.
18143        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18144                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18145        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18146                SystemClock.uptimeMillis());
18147        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18148            // Changed to/from cached state, so apps after it in the LRU
18149            // list may also be changed.
18150            updateOomAdjLocked();
18151        }
18152        return success;
18153    }
18154
18155    final void updateOomAdjLocked() {
18156        final ActivityRecord TOP_ACT = resumedAppLocked();
18157        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18158        final long now = SystemClock.uptimeMillis();
18159        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18160        final int N = mLruProcesses.size();
18161
18162        if (false) {
18163            RuntimeException e = new RuntimeException();
18164            e.fillInStackTrace();
18165            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18166        }
18167
18168        mAdjSeq++;
18169        mNewNumServiceProcs = 0;
18170        mNewNumAServiceProcs = 0;
18171
18172        final int emptyProcessLimit;
18173        final int cachedProcessLimit;
18174        if (mProcessLimit <= 0) {
18175            emptyProcessLimit = cachedProcessLimit = 0;
18176        } else if (mProcessLimit == 1) {
18177            emptyProcessLimit = 1;
18178            cachedProcessLimit = 0;
18179        } else {
18180            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18181            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18182        }
18183
18184        // Let's determine how many processes we have running vs.
18185        // how many slots we have for background processes; we may want
18186        // to put multiple processes in a slot of there are enough of
18187        // them.
18188        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18189                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18190        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18191        if (numEmptyProcs > cachedProcessLimit) {
18192            // If there are more empty processes than our limit on cached
18193            // processes, then use the cached process limit for the factor.
18194            // This ensures that the really old empty processes get pushed
18195            // down to the bottom, so if we are running low on memory we will
18196            // have a better chance at keeping around more cached processes
18197            // instead of a gazillion empty processes.
18198            numEmptyProcs = cachedProcessLimit;
18199        }
18200        int emptyFactor = numEmptyProcs/numSlots;
18201        if (emptyFactor < 1) emptyFactor = 1;
18202        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18203        if (cachedFactor < 1) cachedFactor = 1;
18204        int stepCached = 0;
18205        int stepEmpty = 0;
18206        int numCached = 0;
18207        int numEmpty = 0;
18208        int numTrimming = 0;
18209
18210        mNumNonCachedProcs = 0;
18211        mNumCachedHiddenProcs = 0;
18212
18213        // First update the OOM adjustment for each of the
18214        // application processes based on their current state.
18215        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18216        int nextCachedAdj = curCachedAdj+1;
18217        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18218        int nextEmptyAdj = curEmptyAdj+2;
18219        for (int i=N-1; i>=0; i--) {
18220            ProcessRecord app = mLruProcesses.get(i);
18221            if (!app.killedByAm && app.thread != null) {
18222                app.procStateChanged = false;
18223                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18224
18225                // If we haven't yet assigned the final cached adj
18226                // to the process, do that now.
18227                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18228                    switch (app.curProcState) {
18229                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18230                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18231                            // This process is a cached process holding activities...
18232                            // assign it the next cached value for that type, and then
18233                            // step that cached level.
18234                            app.curRawAdj = curCachedAdj;
18235                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18236                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18237                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18238                                    + ")");
18239                            if (curCachedAdj != nextCachedAdj) {
18240                                stepCached++;
18241                                if (stepCached >= cachedFactor) {
18242                                    stepCached = 0;
18243                                    curCachedAdj = nextCachedAdj;
18244                                    nextCachedAdj += 2;
18245                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18246                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18247                                    }
18248                                }
18249                            }
18250                            break;
18251                        default:
18252                            // For everything else, assign next empty cached process
18253                            // level and bump that up.  Note that this means that
18254                            // long-running services that have dropped down to the
18255                            // cached level will be treated as empty (since their process
18256                            // state is still as a service), which is what we want.
18257                            app.curRawAdj = curEmptyAdj;
18258                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18259                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18260                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18261                                    + ")");
18262                            if (curEmptyAdj != nextEmptyAdj) {
18263                                stepEmpty++;
18264                                if (stepEmpty >= emptyFactor) {
18265                                    stepEmpty = 0;
18266                                    curEmptyAdj = nextEmptyAdj;
18267                                    nextEmptyAdj += 2;
18268                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18269                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18270                                    }
18271                                }
18272                            }
18273                            break;
18274                    }
18275                }
18276
18277                applyOomAdjLocked(app, TOP_APP, true, now);
18278
18279                // Count the number of process types.
18280                switch (app.curProcState) {
18281                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18282                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18283                        mNumCachedHiddenProcs++;
18284                        numCached++;
18285                        if (numCached > cachedProcessLimit) {
18286                            app.kill("cached #" + numCached, true);
18287                        }
18288                        break;
18289                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18290                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18291                                && app.lastActivityTime < oldTime) {
18292                            app.kill("empty for "
18293                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18294                                    / 1000) + "s", true);
18295                        } else {
18296                            numEmpty++;
18297                            if (numEmpty > emptyProcessLimit) {
18298                                app.kill("empty #" + numEmpty, true);
18299                            }
18300                        }
18301                        break;
18302                    default:
18303                        mNumNonCachedProcs++;
18304                        break;
18305                }
18306
18307                if (app.isolated && app.services.size() <= 0) {
18308                    // If this is an isolated process, and there are no
18309                    // services running in it, then the process is no longer
18310                    // needed.  We agressively kill these because we can by
18311                    // definition not re-use the same process again, and it is
18312                    // good to avoid having whatever code was running in them
18313                    // left sitting around after no longer needed.
18314                    app.kill("isolated not needed", true);
18315                }
18316
18317                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18318                        && !app.killedByAm) {
18319                    numTrimming++;
18320                }
18321            }
18322        }
18323
18324        mNumServiceProcs = mNewNumServiceProcs;
18325
18326        // Now determine the memory trimming level of background processes.
18327        // Unfortunately we need to start at the back of the list to do this
18328        // properly.  We only do this if the number of background apps we
18329        // are managing to keep around is less than half the maximum we desire;
18330        // if we are keeping a good number around, we'll let them use whatever
18331        // memory they want.
18332        final int numCachedAndEmpty = numCached + numEmpty;
18333        int memFactor;
18334        if (numCached <= ProcessList.TRIM_CACHED_APPS
18335                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18336            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18337                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18338            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18339                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18340            } else {
18341                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18342            }
18343        } else {
18344            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18345        }
18346        // We always allow the memory level to go up (better).  We only allow it to go
18347        // down if we are in a state where that is allowed, *and* the total number of processes
18348        // has gone down since last time.
18349        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18350                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18351                + " last=" + mLastNumProcesses);
18352        if (memFactor > mLastMemoryLevel) {
18353            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18354                memFactor = mLastMemoryLevel;
18355                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18356            }
18357        }
18358        mLastMemoryLevel = memFactor;
18359        mLastNumProcesses = mLruProcesses.size();
18360        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18361        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18362        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18363            if (mLowRamStartTime == 0) {
18364                mLowRamStartTime = now;
18365            }
18366            int step = 0;
18367            int fgTrimLevel;
18368            switch (memFactor) {
18369                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18370                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18371                    break;
18372                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18373                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18374                    break;
18375                default:
18376                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18377                    break;
18378            }
18379            int factor = numTrimming/3;
18380            int minFactor = 2;
18381            if (mHomeProcess != null) minFactor++;
18382            if (mPreviousProcess != null) minFactor++;
18383            if (factor < minFactor) factor = minFactor;
18384            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18385            for (int i=N-1; i>=0; i--) {
18386                ProcessRecord app = mLruProcesses.get(i);
18387                if (allChanged || app.procStateChanged) {
18388                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18389                    app.procStateChanged = false;
18390                }
18391                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18392                        && !app.killedByAm) {
18393                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18394                        try {
18395                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18396                                    "Trimming memory of " + app.processName
18397                                    + " to " + curLevel);
18398                            app.thread.scheduleTrimMemory(curLevel);
18399                        } catch (RemoteException e) {
18400                        }
18401                        if (false) {
18402                            // For now we won't do this; our memory trimming seems
18403                            // to be good enough at this point that destroying
18404                            // activities causes more harm than good.
18405                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18406                                    && app != mHomeProcess && app != mPreviousProcess) {
18407                                // Need to do this on its own message because the stack may not
18408                                // be in a consistent state at this point.
18409                                // For these apps we will also finish their activities
18410                                // to help them free memory.
18411                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18412                            }
18413                        }
18414                    }
18415                    app.trimMemoryLevel = curLevel;
18416                    step++;
18417                    if (step >= factor) {
18418                        step = 0;
18419                        switch (curLevel) {
18420                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18421                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18422                                break;
18423                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18424                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18425                                break;
18426                        }
18427                    }
18428                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18429                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18430                            && app.thread != null) {
18431                        try {
18432                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18433                                    "Trimming memory of heavy-weight " + app.processName
18434                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18435                            app.thread.scheduleTrimMemory(
18436                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18437                        } catch (RemoteException e) {
18438                        }
18439                    }
18440                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18441                } else {
18442                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18443                            || app.systemNoUi) && app.pendingUiClean) {
18444                        // If this application is now in the background and it
18445                        // had done UI, then give it the special trim level to
18446                        // have it free UI resources.
18447                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18448                        if (app.trimMemoryLevel < level && app.thread != null) {
18449                            try {
18450                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18451                                        "Trimming memory of bg-ui " + app.processName
18452                                        + " to " + level);
18453                                app.thread.scheduleTrimMemory(level);
18454                            } catch (RemoteException e) {
18455                            }
18456                        }
18457                        app.pendingUiClean = false;
18458                    }
18459                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18460                        try {
18461                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18462                                    "Trimming memory of fg " + app.processName
18463                                    + " to " + fgTrimLevel);
18464                            app.thread.scheduleTrimMemory(fgTrimLevel);
18465                        } catch (RemoteException e) {
18466                        }
18467                    }
18468                    app.trimMemoryLevel = fgTrimLevel;
18469                }
18470            }
18471        } else {
18472            if (mLowRamStartTime != 0) {
18473                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18474                mLowRamStartTime = 0;
18475            }
18476            for (int i=N-1; i>=0; i--) {
18477                ProcessRecord app = mLruProcesses.get(i);
18478                if (allChanged || app.procStateChanged) {
18479                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18480                    app.procStateChanged = false;
18481                }
18482                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18483                        || app.systemNoUi) && app.pendingUiClean) {
18484                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18485                            && app.thread != null) {
18486                        try {
18487                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18488                                    "Trimming memory of ui hidden " + app.processName
18489                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18490                            app.thread.scheduleTrimMemory(
18491                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18492                        } catch (RemoteException e) {
18493                        }
18494                    }
18495                    app.pendingUiClean = false;
18496                }
18497                app.trimMemoryLevel = 0;
18498            }
18499        }
18500
18501        if (mAlwaysFinishActivities) {
18502            // Need to do this on its own message because the stack may not
18503            // be in a consistent state at this point.
18504            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18505        }
18506
18507        if (allChanged) {
18508            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18509        }
18510
18511        if (mProcessStats.shouldWriteNowLocked(now)) {
18512            mHandler.post(new Runnable() {
18513                @Override public void run() {
18514                    synchronized (ActivityManagerService.this) {
18515                        mProcessStats.writeStateAsyncLocked();
18516                    }
18517                }
18518            });
18519        }
18520
18521        if (DEBUG_OOM_ADJ) {
18522            if (false) {
18523                RuntimeException here = new RuntimeException("here");
18524                here.fillInStackTrace();
18525                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18526            } else {
18527                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18528            }
18529        }
18530    }
18531
18532    final void trimApplications() {
18533        synchronized (this) {
18534            int i;
18535
18536            // First remove any unused application processes whose package
18537            // has been removed.
18538            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18539                final ProcessRecord app = mRemovedProcesses.get(i);
18540                if (app.activities.size() == 0
18541                        && app.curReceiver == null && app.services.size() == 0) {
18542                    Slog.i(
18543                        TAG, "Exiting empty application process "
18544                        + app.processName + " ("
18545                        + (app.thread != null ? app.thread.asBinder() : null)
18546                        + ")\n");
18547                    if (app.pid > 0 && app.pid != MY_PID) {
18548                        app.kill("empty", false);
18549                    } else {
18550                        try {
18551                            app.thread.scheduleExit();
18552                        } catch (Exception e) {
18553                            // Ignore exceptions.
18554                        }
18555                    }
18556                    cleanUpApplicationRecordLocked(app, false, true, -1);
18557                    mRemovedProcesses.remove(i);
18558
18559                    if (app.persistent) {
18560                        addAppLocked(app.info, false, null /* ABI override */);
18561                    }
18562                }
18563            }
18564
18565            // Now update the oom adj for all processes.
18566            updateOomAdjLocked();
18567        }
18568    }
18569
18570    /** This method sends the specified signal to each of the persistent apps */
18571    public void signalPersistentProcesses(int sig) throws RemoteException {
18572        if (sig != Process.SIGNAL_USR1) {
18573            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18574        }
18575
18576        synchronized (this) {
18577            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18578                    != PackageManager.PERMISSION_GRANTED) {
18579                throw new SecurityException("Requires permission "
18580                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18581            }
18582
18583            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18584                ProcessRecord r = mLruProcesses.get(i);
18585                if (r.thread != null && r.persistent) {
18586                    Process.sendSignal(r.pid, sig);
18587                }
18588            }
18589        }
18590    }
18591
18592    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18593        if (proc == null || proc == mProfileProc) {
18594            proc = mProfileProc;
18595            profileType = mProfileType;
18596            clearProfilerLocked();
18597        }
18598        if (proc == null) {
18599            return;
18600        }
18601        try {
18602            proc.thread.profilerControl(false, null, profileType);
18603        } catch (RemoteException e) {
18604            throw new IllegalStateException("Process disappeared");
18605        }
18606    }
18607
18608    private void clearProfilerLocked() {
18609        if (mProfileFd != null) {
18610            try {
18611                mProfileFd.close();
18612            } catch (IOException e) {
18613            }
18614        }
18615        mProfileApp = null;
18616        mProfileProc = null;
18617        mProfileFile = null;
18618        mProfileType = 0;
18619        mAutoStopProfiler = false;
18620        mSamplingInterval = 0;
18621    }
18622
18623    public boolean profileControl(String process, int userId, boolean start,
18624            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18625
18626        try {
18627            synchronized (this) {
18628                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18629                // its own permission.
18630                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18631                        != PackageManager.PERMISSION_GRANTED) {
18632                    throw new SecurityException("Requires permission "
18633                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18634                }
18635
18636                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18637                    throw new IllegalArgumentException("null profile info or fd");
18638                }
18639
18640                ProcessRecord proc = null;
18641                if (process != null) {
18642                    proc = findProcessLocked(process, userId, "profileControl");
18643                }
18644
18645                if (start && (proc == null || proc.thread == null)) {
18646                    throw new IllegalArgumentException("Unknown process: " + process);
18647                }
18648
18649                if (start) {
18650                    stopProfilerLocked(null, 0);
18651                    setProfileApp(proc.info, proc.processName, profilerInfo);
18652                    mProfileProc = proc;
18653                    mProfileType = profileType;
18654                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18655                    try {
18656                        fd = fd.dup();
18657                    } catch (IOException e) {
18658                        fd = null;
18659                    }
18660                    profilerInfo.profileFd = fd;
18661                    proc.thread.profilerControl(start, profilerInfo, profileType);
18662                    fd = null;
18663                    mProfileFd = null;
18664                } else {
18665                    stopProfilerLocked(proc, profileType);
18666                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18667                        try {
18668                            profilerInfo.profileFd.close();
18669                        } catch (IOException e) {
18670                        }
18671                    }
18672                }
18673
18674                return true;
18675            }
18676        } catch (RemoteException e) {
18677            throw new IllegalStateException("Process disappeared");
18678        } finally {
18679            if (profilerInfo != null && profilerInfo.profileFd != null) {
18680                try {
18681                    profilerInfo.profileFd.close();
18682                } catch (IOException e) {
18683                }
18684            }
18685        }
18686    }
18687
18688    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18689        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18690                userId, true, ALLOW_FULL_ONLY, callName, null);
18691        ProcessRecord proc = null;
18692        try {
18693            int pid = Integer.parseInt(process);
18694            synchronized (mPidsSelfLocked) {
18695                proc = mPidsSelfLocked.get(pid);
18696            }
18697        } catch (NumberFormatException e) {
18698        }
18699
18700        if (proc == null) {
18701            ArrayMap<String, SparseArray<ProcessRecord>> all
18702                    = mProcessNames.getMap();
18703            SparseArray<ProcessRecord> procs = all.get(process);
18704            if (procs != null && procs.size() > 0) {
18705                proc = procs.valueAt(0);
18706                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18707                    for (int i=1; i<procs.size(); i++) {
18708                        ProcessRecord thisProc = procs.valueAt(i);
18709                        if (thisProc.userId == userId) {
18710                            proc = thisProc;
18711                            break;
18712                        }
18713                    }
18714                }
18715            }
18716        }
18717
18718        return proc;
18719    }
18720
18721    public boolean dumpHeap(String process, int userId, boolean managed,
18722            String path, ParcelFileDescriptor fd) throws RemoteException {
18723
18724        try {
18725            synchronized (this) {
18726                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18727                // its own permission (same as profileControl).
18728                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18729                        != PackageManager.PERMISSION_GRANTED) {
18730                    throw new SecurityException("Requires permission "
18731                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18732                }
18733
18734                if (fd == null) {
18735                    throw new IllegalArgumentException("null fd");
18736                }
18737
18738                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18739                if (proc == null || proc.thread == null) {
18740                    throw new IllegalArgumentException("Unknown process: " + process);
18741                }
18742
18743                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18744                if (!isDebuggable) {
18745                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18746                        throw new SecurityException("Process not debuggable: " + proc);
18747                    }
18748                }
18749
18750                proc.thread.dumpHeap(managed, path, fd);
18751                fd = null;
18752                return true;
18753            }
18754        } catch (RemoteException e) {
18755            throw new IllegalStateException("Process disappeared");
18756        } finally {
18757            if (fd != null) {
18758                try {
18759                    fd.close();
18760                } catch (IOException e) {
18761                }
18762            }
18763        }
18764    }
18765
18766    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18767    public void monitor() {
18768        synchronized (this) { }
18769    }
18770
18771    void onCoreSettingsChange(Bundle settings) {
18772        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18773            ProcessRecord processRecord = mLruProcesses.get(i);
18774            try {
18775                if (processRecord.thread != null) {
18776                    processRecord.thread.setCoreSettings(settings);
18777                }
18778            } catch (RemoteException re) {
18779                /* ignore */
18780            }
18781        }
18782    }
18783
18784    // Multi-user methods
18785
18786    /**
18787     * Start user, if its not already running, but don't bring it to foreground.
18788     */
18789    @Override
18790    public boolean startUserInBackground(final int userId) {
18791        return startUser(userId, /* foreground */ false);
18792    }
18793
18794    /**
18795     * Start user, if its not already running, and bring it to foreground.
18796     */
18797    boolean startUserInForeground(final int userId, Dialog dlg) {
18798        boolean result = startUser(userId, /* foreground */ true);
18799        dlg.dismiss();
18800        return result;
18801    }
18802
18803    /**
18804     * Refreshes the list of users related to the current user when either a
18805     * user switch happens or when a new related user is started in the
18806     * background.
18807     */
18808    private void updateCurrentProfileIdsLocked() {
18809        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18810                mCurrentUserId, false /* enabledOnly */);
18811        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18812        for (int i = 0; i < currentProfileIds.length; i++) {
18813            currentProfileIds[i] = profiles.get(i).id;
18814        }
18815        mCurrentProfileIds = currentProfileIds;
18816
18817        synchronized (mUserProfileGroupIdsSelfLocked) {
18818            mUserProfileGroupIdsSelfLocked.clear();
18819            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18820            for (int i = 0; i < users.size(); i++) {
18821                UserInfo user = users.get(i);
18822                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18823                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18824                }
18825            }
18826        }
18827    }
18828
18829    private Set getProfileIdsLocked(int userId) {
18830        Set userIds = new HashSet<Integer>();
18831        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18832                userId, false /* enabledOnly */);
18833        for (UserInfo user : profiles) {
18834            userIds.add(Integer.valueOf(user.id));
18835        }
18836        return userIds;
18837    }
18838
18839    @Override
18840    public boolean switchUser(final int userId) {
18841        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18842        String userName;
18843        synchronized (this) {
18844            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18845            if (userInfo == null) {
18846                Slog.w(TAG, "No user info for user #" + userId);
18847                return false;
18848            }
18849            if (userInfo.isManagedProfile()) {
18850                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18851                return false;
18852            }
18853            userName = userInfo.name;
18854            mTargetUserId = userId;
18855        }
18856        mHandler.removeMessages(START_USER_SWITCH_MSG);
18857        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18858        return true;
18859    }
18860
18861    private void showUserSwitchDialog(int userId, String userName) {
18862        // The dialog will show and then initiate the user switch by calling startUserInForeground
18863        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18864                true /* above system */);
18865        d.show();
18866    }
18867
18868    private boolean startUser(final int userId, final boolean foreground) {
18869        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18870                != PackageManager.PERMISSION_GRANTED) {
18871            String msg = "Permission Denial: switchUser() from pid="
18872                    + Binder.getCallingPid()
18873                    + ", uid=" + Binder.getCallingUid()
18874                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18875            Slog.w(TAG, msg);
18876            throw new SecurityException(msg);
18877        }
18878
18879        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18880
18881        final long ident = Binder.clearCallingIdentity();
18882        try {
18883            synchronized (this) {
18884                final int oldUserId = mCurrentUserId;
18885                if (oldUserId == userId) {
18886                    return true;
18887                }
18888
18889                mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18890
18891                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18892                if (userInfo == null) {
18893                    Slog.w(TAG, "No user info for user #" + userId);
18894                    return false;
18895                }
18896                if (foreground && userInfo.isManagedProfile()) {
18897                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18898                    return false;
18899                }
18900
18901                if (foreground) {
18902                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18903                            R.anim.screen_user_enter);
18904                }
18905
18906                boolean needStart = false;
18907
18908                // If the user we are switching to is not currently started, then
18909                // we need to start it now.
18910                if (mStartedUsers.get(userId) == null) {
18911                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18912                    updateStartedUserArrayLocked();
18913                    needStart = true;
18914                }
18915
18916                final Integer userIdInt = Integer.valueOf(userId);
18917                mUserLru.remove(userIdInt);
18918                mUserLru.add(userIdInt);
18919
18920                if (foreground) {
18921                    mCurrentUserId = userId;
18922                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18923                    updateCurrentProfileIdsLocked();
18924                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18925                    // Once the internal notion of the active user has switched, we lock the device
18926                    // with the option to show the user switcher on the keyguard.
18927                    mWindowManager.lockNow(null);
18928                } else {
18929                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18930                    updateCurrentProfileIdsLocked();
18931                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18932                    mUserLru.remove(currentUserIdInt);
18933                    mUserLru.add(currentUserIdInt);
18934                }
18935
18936                final UserStartedState uss = mStartedUsers.get(userId);
18937
18938                // Make sure user is in the started state.  If it is currently
18939                // stopping, we need to knock that off.
18940                if (uss.mState == UserStartedState.STATE_STOPPING) {
18941                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18942                    // so we can just fairly silently bring the user back from
18943                    // the almost-dead.
18944                    uss.mState = UserStartedState.STATE_RUNNING;
18945                    updateStartedUserArrayLocked();
18946                    needStart = true;
18947                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18948                    // This means ACTION_SHUTDOWN has been sent, so we will
18949                    // need to treat this as a new boot of the user.
18950                    uss.mState = UserStartedState.STATE_BOOTING;
18951                    updateStartedUserArrayLocked();
18952                    needStart = true;
18953                }
18954
18955                if (uss.mState == UserStartedState.STATE_BOOTING) {
18956                    // Booting up a new user, need to tell system services about it.
18957                    // Note that this is on the same handler as scheduling of broadcasts,
18958                    // which is important because it needs to go first.
18959                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18960                }
18961
18962                if (foreground) {
18963                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18964                            oldUserId));
18965                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18966                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18967                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18968                            oldUserId, userId, uss));
18969                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18970                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18971                }
18972
18973                if (needStart) {
18974                    // Send USER_STARTED broadcast
18975                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18976                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18977                            | Intent.FLAG_RECEIVER_FOREGROUND);
18978                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18979                    broadcastIntentLocked(null, null, intent,
18980                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18981                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18982                }
18983
18984                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18985                    if (userId != UserHandle.USER_OWNER) {
18986                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18987                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18988                        broadcastIntentLocked(null, null, intent, null,
18989                                new IIntentReceiver.Stub() {
18990                                    public void performReceive(Intent intent, int resultCode,
18991                                            String data, Bundle extras, boolean ordered,
18992                                            boolean sticky, int sendingUser) {
18993                                        onUserInitialized(uss, foreground, oldUserId, userId);
18994                                    }
18995                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18996                                true, false, MY_PID, Process.SYSTEM_UID,
18997                                userId);
18998                        uss.initializing = true;
18999                    } else {
19000                        getUserManagerLocked().makeInitialized(userInfo.id);
19001                    }
19002                }
19003
19004                if (foreground) {
19005                    if (!uss.initializing) {
19006                        moveUserToForeground(uss, oldUserId, userId);
19007                    }
19008                } else {
19009                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19010                }
19011
19012                if (needStart) {
19013                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19014                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19015                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19016                    broadcastIntentLocked(null, null, intent,
19017                            null, new IIntentReceiver.Stub() {
19018                                @Override
19019                                public void performReceive(Intent intent, int resultCode, String data,
19020                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19021                                        throws RemoteException {
19022                                }
19023                            }, 0, null, null,
19024                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19025                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19026                }
19027            }
19028        } finally {
19029            Binder.restoreCallingIdentity(ident);
19030        }
19031
19032        return true;
19033    }
19034
19035    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19036        long ident = Binder.clearCallingIdentity();
19037        try {
19038            Intent intent;
19039            if (oldUserId >= 0) {
19040                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19041                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19042                int count = profiles.size();
19043                for (int i = 0; i < count; i++) {
19044                    int profileUserId = profiles.get(i).id;
19045                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19046                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19047                            | Intent.FLAG_RECEIVER_FOREGROUND);
19048                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19049                    broadcastIntentLocked(null, null, intent,
19050                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19051                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19052                }
19053            }
19054            if (newUserId >= 0) {
19055                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19056                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19057                int count = profiles.size();
19058                for (int i = 0; i < count; i++) {
19059                    int profileUserId = profiles.get(i).id;
19060                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19061                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19062                            | Intent.FLAG_RECEIVER_FOREGROUND);
19063                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19064                    broadcastIntentLocked(null, null, intent,
19065                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19066                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19067                }
19068                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19069                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19070                        | Intent.FLAG_RECEIVER_FOREGROUND);
19071                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19072                broadcastIntentLocked(null, null, intent,
19073                        null, null, 0, null, null,
19074                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19075                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19076            }
19077        } finally {
19078            Binder.restoreCallingIdentity(ident);
19079        }
19080    }
19081
19082    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19083            final int newUserId) {
19084        final int N = mUserSwitchObservers.beginBroadcast();
19085        if (N > 0) {
19086            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19087                int mCount = 0;
19088                @Override
19089                public void sendResult(Bundle data) throws RemoteException {
19090                    synchronized (ActivityManagerService.this) {
19091                        if (mCurUserSwitchCallback == this) {
19092                            mCount++;
19093                            if (mCount == N) {
19094                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19095                            }
19096                        }
19097                    }
19098                }
19099            };
19100            synchronized (this) {
19101                uss.switching = true;
19102                mCurUserSwitchCallback = callback;
19103            }
19104            for (int i=0; i<N; i++) {
19105                try {
19106                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19107                            newUserId, callback);
19108                } catch (RemoteException e) {
19109                }
19110            }
19111        } else {
19112            synchronized (this) {
19113                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19114            }
19115        }
19116        mUserSwitchObservers.finishBroadcast();
19117    }
19118
19119    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19120        synchronized (this) {
19121            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19122            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19123        }
19124    }
19125
19126    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19127        mCurUserSwitchCallback = null;
19128        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19129        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19130                oldUserId, newUserId, uss));
19131    }
19132
19133    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19134        synchronized (this) {
19135            if (foreground) {
19136                moveUserToForeground(uss, oldUserId, newUserId);
19137            }
19138        }
19139
19140        completeSwitchAndInitalize(uss, newUserId, true, false);
19141    }
19142
19143    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19144        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19145        if (homeInFront) {
19146            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19147        } else {
19148            mStackSupervisor.resumeTopActivitiesLocked();
19149        }
19150        EventLogTags.writeAmSwitchUser(newUserId);
19151        getUserManagerLocked().userForeground(newUserId);
19152        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19153    }
19154
19155    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19156        completeSwitchAndInitalize(uss, newUserId, false, true);
19157    }
19158
19159    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19160            boolean clearInitializing, boolean clearSwitching) {
19161        boolean unfrozen = false;
19162        synchronized (this) {
19163            if (clearInitializing) {
19164                uss.initializing = false;
19165                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19166            }
19167            if (clearSwitching) {
19168                uss.switching = false;
19169            }
19170            if (!uss.switching && !uss.initializing) {
19171                mWindowManager.stopFreezingScreen();
19172                unfrozen = true;
19173            }
19174        }
19175        if (unfrozen) {
19176            final int N = mUserSwitchObservers.beginBroadcast();
19177            for (int i=0; i<N; i++) {
19178                try {
19179                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19180                } catch (RemoteException e) {
19181                }
19182            }
19183            mUserSwitchObservers.finishBroadcast();
19184        }
19185        stopGuestUserIfBackground();
19186    }
19187
19188    /**
19189     * Stops the guest user if it has gone to the background.
19190     */
19191    private void stopGuestUserIfBackground() {
19192        synchronized (this) {
19193            final int num = mUserLru.size();
19194            for (int i = 0; i < num; i++) {
19195                Integer oldUserId = mUserLru.get(i);
19196                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19197                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19198                        || oldUss.mState == UserStartedState.STATE_STOPPING
19199                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19200                    continue;
19201                }
19202                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19203                if (userInfo.isGuest()) {
19204                    // This is a user to be stopped.
19205                    stopUserLocked(oldUserId, null);
19206                    break;
19207                }
19208            }
19209        }
19210    }
19211
19212    void scheduleStartProfilesLocked() {
19213        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19214            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19215                    DateUtils.SECOND_IN_MILLIS);
19216        }
19217    }
19218
19219    void startProfilesLocked() {
19220        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19221        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19222                mCurrentUserId, false /* enabledOnly */);
19223        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19224        for (UserInfo user : profiles) {
19225            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19226                    && user.id != mCurrentUserId) {
19227                toStart.add(user);
19228            }
19229        }
19230        final int n = toStart.size();
19231        int i = 0;
19232        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19233            startUserInBackground(toStart.get(i).id);
19234        }
19235        if (i < n) {
19236            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19237        }
19238    }
19239
19240    void finishUserBoot(UserStartedState uss) {
19241        synchronized (this) {
19242            if (uss.mState == UserStartedState.STATE_BOOTING
19243                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19244                uss.mState = UserStartedState.STATE_RUNNING;
19245                final int userId = uss.mHandle.getIdentifier();
19246                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19247                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19248                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19249                broadcastIntentLocked(null, null, intent,
19250                        null, null, 0, null, null,
19251                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19252                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19253            }
19254        }
19255    }
19256
19257    void finishUserSwitch(UserStartedState uss) {
19258        synchronized (this) {
19259            finishUserBoot(uss);
19260
19261            startProfilesLocked();
19262
19263            int num = mUserLru.size();
19264            int i = 0;
19265            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19266                Integer oldUserId = mUserLru.get(i);
19267                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19268                if (oldUss == null) {
19269                    // Shouldn't happen, but be sane if it does.
19270                    mUserLru.remove(i);
19271                    num--;
19272                    continue;
19273                }
19274                if (oldUss.mState == UserStartedState.STATE_STOPPING
19275                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19276                    // This user is already stopping, doesn't count.
19277                    num--;
19278                    i++;
19279                    continue;
19280                }
19281                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19282                    // Owner and current can't be stopped, but count as running.
19283                    i++;
19284                    continue;
19285                }
19286                // This is a user to be stopped.
19287                stopUserLocked(oldUserId, null);
19288                num--;
19289                i++;
19290            }
19291        }
19292    }
19293
19294    @Override
19295    public int stopUser(final int userId, final IStopUserCallback callback) {
19296        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19297                != PackageManager.PERMISSION_GRANTED) {
19298            String msg = "Permission Denial: switchUser() from pid="
19299                    + Binder.getCallingPid()
19300                    + ", uid=" + Binder.getCallingUid()
19301                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19302            Slog.w(TAG, msg);
19303            throw new SecurityException(msg);
19304        }
19305        if (userId <= 0) {
19306            throw new IllegalArgumentException("Can't stop primary user " + userId);
19307        }
19308        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19309        synchronized (this) {
19310            return stopUserLocked(userId, callback);
19311        }
19312    }
19313
19314    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19315        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19316        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19317            return ActivityManager.USER_OP_IS_CURRENT;
19318        }
19319
19320        final UserStartedState uss = mStartedUsers.get(userId);
19321        if (uss == null) {
19322            // User is not started, nothing to do...  but we do need to
19323            // callback if requested.
19324            if (callback != null) {
19325                mHandler.post(new Runnable() {
19326                    @Override
19327                    public void run() {
19328                        try {
19329                            callback.userStopped(userId);
19330                        } catch (RemoteException e) {
19331                        }
19332                    }
19333                });
19334            }
19335            return ActivityManager.USER_OP_SUCCESS;
19336        }
19337
19338        if (callback != null) {
19339            uss.mStopCallbacks.add(callback);
19340        }
19341
19342        if (uss.mState != UserStartedState.STATE_STOPPING
19343                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19344            uss.mState = UserStartedState.STATE_STOPPING;
19345            updateStartedUserArrayLocked();
19346
19347            long ident = Binder.clearCallingIdentity();
19348            try {
19349                // We are going to broadcast ACTION_USER_STOPPING and then
19350                // once that is done send a final ACTION_SHUTDOWN and then
19351                // stop the user.
19352                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19353                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19354                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19355                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19356                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19357                // This is the result receiver for the final shutdown broadcast.
19358                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19359                    @Override
19360                    public void performReceive(Intent intent, int resultCode, String data,
19361                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19362                        finishUserStop(uss);
19363                    }
19364                };
19365                // This is the result receiver for the initial stopping broadcast.
19366                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19367                    @Override
19368                    public void performReceive(Intent intent, int resultCode, String data,
19369                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19370                        // On to the next.
19371                        synchronized (ActivityManagerService.this) {
19372                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19373                                // Whoops, we are being started back up.  Abort, abort!
19374                                return;
19375                            }
19376                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19377                        }
19378                        mBatteryStatsService.noteEvent(
19379                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19380                                Integer.toString(userId), userId);
19381                        mSystemServiceManager.stopUser(userId);
19382                        broadcastIntentLocked(null, null, shutdownIntent,
19383                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19384                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19385                    }
19386                };
19387                // Kick things off.
19388                broadcastIntentLocked(null, null, stoppingIntent,
19389                        null, stoppingReceiver, 0, null, null,
19390                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19391                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19392            } finally {
19393                Binder.restoreCallingIdentity(ident);
19394            }
19395        }
19396
19397        return ActivityManager.USER_OP_SUCCESS;
19398    }
19399
19400    void finishUserStop(UserStartedState uss) {
19401        final int userId = uss.mHandle.getIdentifier();
19402        boolean stopped;
19403        ArrayList<IStopUserCallback> callbacks;
19404        synchronized (this) {
19405            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19406            if (mStartedUsers.get(userId) != uss) {
19407                stopped = false;
19408            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19409                stopped = false;
19410            } else {
19411                stopped = true;
19412                // User can no longer run.
19413                mStartedUsers.remove(userId);
19414                mUserLru.remove(Integer.valueOf(userId));
19415                updateStartedUserArrayLocked();
19416
19417                // Clean up all state and processes associated with the user.
19418                // Kill all the processes for the user.
19419                forceStopUserLocked(userId, "finish user");
19420            }
19421
19422            // Explicitly remove the old information in mRecentTasks.
19423            removeRecentTasksForUserLocked(userId);
19424        }
19425
19426        for (int i=0; i<callbacks.size(); i++) {
19427            try {
19428                if (stopped) callbacks.get(i).userStopped(userId);
19429                else callbacks.get(i).userStopAborted(userId);
19430            } catch (RemoteException e) {
19431            }
19432        }
19433
19434        if (stopped) {
19435            mSystemServiceManager.cleanupUser(userId);
19436            synchronized (this) {
19437                mStackSupervisor.removeUserLocked(userId);
19438            }
19439        }
19440    }
19441
19442    @Override
19443    public UserInfo getCurrentUser() {
19444        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19445                != PackageManager.PERMISSION_GRANTED) && (
19446                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19447                != PackageManager.PERMISSION_GRANTED)) {
19448            String msg = "Permission Denial: getCurrentUser() from pid="
19449                    + Binder.getCallingPid()
19450                    + ", uid=" + Binder.getCallingUid()
19451                    + " requires " + INTERACT_ACROSS_USERS;
19452            Slog.w(TAG, msg);
19453            throw new SecurityException(msg);
19454        }
19455        synchronized (this) {
19456            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19457            return getUserManagerLocked().getUserInfo(userId);
19458        }
19459    }
19460
19461    int getCurrentUserIdLocked() {
19462        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19463    }
19464
19465    @Override
19466    public boolean isUserRunning(int userId, boolean orStopped) {
19467        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19468                != PackageManager.PERMISSION_GRANTED) {
19469            String msg = "Permission Denial: isUserRunning() from pid="
19470                    + Binder.getCallingPid()
19471                    + ", uid=" + Binder.getCallingUid()
19472                    + " requires " + INTERACT_ACROSS_USERS;
19473            Slog.w(TAG, msg);
19474            throw new SecurityException(msg);
19475        }
19476        synchronized (this) {
19477            return isUserRunningLocked(userId, orStopped);
19478        }
19479    }
19480
19481    boolean isUserRunningLocked(int userId, boolean orStopped) {
19482        UserStartedState state = mStartedUsers.get(userId);
19483        if (state == null) {
19484            return false;
19485        }
19486        if (orStopped) {
19487            return true;
19488        }
19489        return state.mState != UserStartedState.STATE_STOPPING
19490                && state.mState != UserStartedState.STATE_SHUTDOWN;
19491    }
19492
19493    @Override
19494    public int[] getRunningUserIds() {
19495        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19496                != PackageManager.PERMISSION_GRANTED) {
19497            String msg = "Permission Denial: isUserRunning() from pid="
19498                    + Binder.getCallingPid()
19499                    + ", uid=" + Binder.getCallingUid()
19500                    + " requires " + INTERACT_ACROSS_USERS;
19501            Slog.w(TAG, msg);
19502            throw new SecurityException(msg);
19503        }
19504        synchronized (this) {
19505            return mStartedUserArray;
19506        }
19507    }
19508
19509    private void updateStartedUserArrayLocked() {
19510        int num = 0;
19511        for (int i=0; i<mStartedUsers.size();  i++) {
19512            UserStartedState uss = mStartedUsers.valueAt(i);
19513            // This list does not include stopping users.
19514            if (uss.mState != UserStartedState.STATE_STOPPING
19515                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19516                num++;
19517            }
19518        }
19519        mStartedUserArray = new int[num];
19520        num = 0;
19521        for (int i=0; i<mStartedUsers.size();  i++) {
19522            UserStartedState uss = mStartedUsers.valueAt(i);
19523            if (uss.mState != UserStartedState.STATE_STOPPING
19524                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19525                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19526                num++;
19527            }
19528        }
19529    }
19530
19531    @Override
19532    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19533        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19534                != PackageManager.PERMISSION_GRANTED) {
19535            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19536                    + Binder.getCallingPid()
19537                    + ", uid=" + Binder.getCallingUid()
19538                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19539            Slog.w(TAG, msg);
19540            throw new SecurityException(msg);
19541        }
19542
19543        mUserSwitchObservers.register(observer);
19544    }
19545
19546    @Override
19547    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19548        mUserSwitchObservers.unregister(observer);
19549    }
19550
19551    private boolean userExists(int userId) {
19552        if (userId == 0) {
19553            return true;
19554        }
19555        UserManagerService ums = getUserManagerLocked();
19556        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19557    }
19558
19559    int[] getUsersLocked() {
19560        UserManagerService ums = getUserManagerLocked();
19561        return ums != null ? ums.getUserIds() : new int[] { 0 };
19562    }
19563
19564    UserManagerService getUserManagerLocked() {
19565        if (mUserManager == null) {
19566            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19567            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19568        }
19569        return mUserManager;
19570    }
19571
19572    private int applyUserId(int uid, int userId) {
19573        return UserHandle.getUid(userId, uid);
19574    }
19575
19576    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19577        if (info == null) return null;
19578        ApplicationInfo newInfo = new ApplicationInfo(info);
19579        newInfo.uid = applyUserId(info.uid, userId);
19580        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19581                + info.packageName;
19582        return newInfo;
19583    }
19584
19585    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19586        if (aInfo == null
19587                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19588            return aInfo;
19589        }
19590
19591        ActivityInfo info = new ActivityInfo(aInfo);
19592        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19593        return info;
19594    }
19595
19596    private final class LocalService extends ActivityManagerInternal {
19597        @Override
19598        public void onWakefulnessChanged(int wakefulness) {
19599            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19600        }
19601
19602        @Override
19603        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19604                String processName, String abiOverride, int uid, Runnable crashHandler) {
19605            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19606                    processName, abiOverride, uid, crashHandler);
19607        }
19608    }
19609
19610    /**
19611     * An implementation of IAppTask, that allows an app to manage its own tasks via
19612     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19613     * only the process that calls getAppTasks() can call the AppTask methods.
19614     */
19615    class AppTaskImpl extends IAppTask.Stub {
19616        private int mTaskId;
19617        private int mCallingUid;
19618
19619        public AppTaskImpl(int taskId, int callingUid) {
19620            mTaskId = taskId;
19621            mCallingUid = callingUid;
19622        }
19623
19624        private void checkCaller() {
19625            if (mCallingUid != Binder.getCallingUid()) {
19626                throw new SecurityException("Caller " + mCallingUid
19627                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19628            }
19629        }
19630
19631        @Override
19632        public void finishAndRemoveTask() {
19633            checkCaller();
19634
19635            synchronized (ActivityManagerService.this) {
19636                long origId = Binder.clearCallingIdentity();
19637                try {
19638                    if (!removeTaskByIdLocked(mTaskId, false)) {
19639                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19640                    }
19641                } finally {
19642                    Binder.restoreCallingIdentity(origId);
19643                }
19644            }
19645        }
19646
19647        @Override
19648        public ActivityManager.RecentTaskInfo getTaskInfo() {
19649            checkCaller();
19650
19651            synchronized (ActivityManagerService.this) {
19652                long origId = Binder.clearCallingIdentity();
19653                try {
19654                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19655                    if (tr == null) {
19656                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19657                    }
19658                    return createRecentTaskInfoFromTaskRecord(tr);
19659                } finally {
19660                    Binder.restoreCallingIdentity(origId);
19661                }
19662            }
19663        }
19664
19665        @Override
19666        public void moveToFront() {
19667            checkCaller();
19668            // Will bring task to front if it already has a root activity.
19669            startActivityFromRecentsInner(mTaskId, null);
19670        }
19671
19672        @Override
19673        public int startActivity(IBinder whoThread, String callingPackage,
19674                Intent intent, String resolvedType, Bundle options) {
19675            checkCaller();
19676
19677            int callingUser = UserHandle.getCallingUserId();
19678            TaskRecord tr;
19679            IApplicationThread appThread;
19680            synchronized (ActivityManagerService.this) {
19681                tr = recentTaskForIdLocked(mTaskId);
19682                if (tr == null) {
19683                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19684                }
19685                appThread = ApplicationThreadNative.asInterface(whoThread);
19686                if (appThread == null) {
19687                    throw new IllegalArgumentException("Bad app thread " + appThread);
19688                }
19689            }
19690            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19691                    resolvedType, null, null, null, null, 0, 0, null, null,
19692                    null, options, callingUser, null, tr);
19693        }
19694
19695        @Override
19696        public void setExcludeFromRecents(boolean exclude) {
19697            checkCaller();
19698
19699            synchronized (ActivityManagerService.this) {
19700                long origId = Binder.clearCallingIdentity();
19701                try {
19702                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19703                    if (tr == null) {
19704                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19705                    }
19706                    Intent intent = tr.getBaseIntent();
19707                    if (exclude) {
19708                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19709                    } else {
19710                        intent.setFlags(intent.getFlags()
19711                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19712                    }
19713                } finally {
19714                    Binder.restoreCallingIdentity(origId);
19715                }
19716            }
19717        }
19718    }
19719}
19720