ActivityManagerService.java revision 1a4b5a4f02e7d8ff8ff645377d97e6062d36aeaa
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    /**
753     * Backup/restore process management
754     */
755    String mBackupAppName = null;
756    BackupRecord mBackupTarget = null;
757
758    final ProviderMap mProviderMap;
759
760    /**
761     * List of content providers who have clients waiting for them.  The
762     * application is currently being launched and the provider will be
763     * removed from this list once it is published.
764     */
765    final ArrayList<ContentProviderRecord> mLaunchingProviders
766            = new ArrayList<ContentProviderRecord>();
767
768    /**
769     * File storing persisted {@link #mGrantedUriPermissions}.
770     */
771    private final AtomicFile mGrantFile;
772
773    /** XML constants used in {@link #mGrantFile} */
774    private static final String TAG_URI_GRANTS = "uri-grants";
775    private static final String TAG_URI_GRANT = "uri-grant";
776    private static final String ATTR_USER_HANDLE = "userHandle";
777    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
778    private static final String ATTR_TARGET_USER_ID = "targetUserId";
779    private static final String ATTR_SOURCE_PKG = "sourcePkg";
780    private static final String ATTR_TARGET_PKG = "targetPkg";
781    private static final String ATTR_URI = "uri";
782    private static final String ATTR_MODE_FLAGS = "modeFlags";
783    private static final String ATTR_CREATED_TIME = "createdTime";
784    private static final String ATTR_PREFIX = "prefix";
785
786    /**
787     * Global set of specific {@link Uri} permissions that have been granted.
788     * This optimized lookup structure maps from {@link UriPermission#targetUid}
789     * to {@link UriPermission#uri} to {@link UriPermission}.
790     */
791    @GuardedBy("this")
792    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
793            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
794
795    public static class GrantUri {
796        public final int sourceUserId;
797        public final Uri uri;
798        public boolean prefix;
799
800        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
801            this.sourceUserId = sourceUserId;
802            this.uri = uri;
803            this.prefix = prefix;
804        }
805
806        @Override
807        public int hashCode() {
808            int hashCode = 1;
809            hashCode = 31 * hashCode + sourceUserId;
810            hashCode = 31 * hashCode + uri.hashCode();
811            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
812            return hashCode;
813        }
814
815        @Override
816        public boolean equals(Object o) {
817            if (o instanceof GrantUri) {
818                GrantUri other = (GrantUri) o;
819                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
820                        && prefix == other.prefix;
821            }
822            return false;
823        }
824
825        @Override
826        public String toString() {
827            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
828            if (prefix) result += " [prefix]";
829            return result;
830        }
831
832        public String toSafeString() {
833            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
834            if (prefix) result += " [prefix]";
835            return result;
836        }
837
838        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
839            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
840                    ContentProvider.getUriWithoutUserId(uri), false);
841        }
842    }
843
844    CoreSettingsObserver mCoreSettingsObserver;
845
846    /**
847     * Thread-local storage used to carry caller permissions over through
848     * indirect content-provider access.
849     */
850    private class Identity {
851        public final IBinder token;
852        public final int pid;
853        public final int uid;
854
855        Identity(IBinder _token, int _pid, int _uid) {
856            token = _token;
857            pid = _pid;
858            uid = _uid;
859        }
860    }
861
862    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
863
864    /**
865     * All information we have collected about the runtime performance of
866     * any user id that can impact battery performance.
867     */
868    final BatteryStatsService mBatteryStatsService;
869
870    /**
871     * Information about component usage
872     */
873    UsageStatsManagerInternal mUsageStatsService;
874
875    /**
876     * Information about and control over application operations
877     */
878    final AppOpsService mAppOpsService;
879
880    /**
881     * Save recent tasks information across reboots.
882     */
883    final TaskPersister mTaskPersister;
884
885    /**
886     * Current configuration information.  HistoryRecord objects are given
887     * a reference to this object to indicate which configuration they are
888     * currently running in, so this object must be kept immutable.
889     */
890    Configuration mConfiguration = new Configuration();
891
892    /**
893     * Current sequencing integer of the configuration, for skipping old
894     * configurations.
895     */
896    int mConfigurationSeq = 0;
897
898    /**
899     * Hardware-reported OpenGLES version.
900     */
901    final int GL_ES_VERSION;
902
903    /**
904     * List of initialization arguments to pass to all processes when binding applications to them.
905     * For example, references to the commonly used services.
906     */
907    HashMap<String, IBinder> mAppBindArgs;
908
909    /**
910     * Temporary to avoid allocations.  Protected by main lock.
911     */
912    final StringBuilder mStringBuilder = new StringBuilder(256);
913
914    /**
915     * Used to control how we initialize the service.
916     */
917    ComponentName mTopComponent;
918    String mTopAction = Intent.ACTION_MAIN;
919    String mTopData;
920    boolean mProcessesReady = false;
921    boolean mSystemReady = false;
922    boolean mBooting = false;
923    boolean mCallFinishBooting = false;
924    boolean mBootAnimationComplete = false;
925    boolean mWaitingUpdate = false;
926    boolean mDidUpdate = false;
927    boolean mOnBattery = false;
928    boolean mLaunchWarningShown = false;
929
930    Context mContext;
931
932    int mFactoryTest;
933
934    boolean mCheckedForSetup;
935
936    /**
937     * The time at which we will allow normal application switches again,
938     * after a call to {@link #stopAppSwitches()}.
939     */
940    long mAppSwitchesAllowedTime;
941
942    /**
943     * This is set to true after the first switch after mAppSwitchesAllowedTime
944     * is set; any switches after that will clear the time.
945     */
946    boolean mDidAppSwitch;
947
948    /**
949     * Last time (in realtime) at which we checked for power usage.
950     */
951    long mLastPowerCheckRealtime;
952
953    /**
954     * Last time (in uptime) at which we checked for power usage.
955     */
956    long mLastPowerCheckUptime;
957
958    /**
959     * Set while we are wanting to sleep, to prevent any
960     * activities from being started/resumed.
961     */
962    private boolean mSleeping = false;
963
964    /**
965     * Set while we are running a voice interaction.  This overrides
966     * sleeping while it is active.
967     */
968    private boolean mRunningVoice = false;
969
970    /**
971     * State of external calls telling us if the device is awake or asleep.
972     */
973    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
974
975    static final int LOCK_SCREEN_HIDDEN = 0;
976    static final int LOCK_SCREEN_LEAVING = 1;
977    static final int LOCK_SCREEN_SHOWN = 2;
978    /**
979     * State of external call telling us if the lock screen is shown.
980     */
981    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
982
983    /**
984     * Set if we are shutting down the system, similar to sleeping.
985     */
986    boolean mShuttingDown = false;
987
988    /**
989     * Current sequence id for oom_adj computation traversal.
990     */
991    int mAdjSeq = 0;
992
993    /**
994     * Current sequence id for process LRU updating.
995     */
996    int mLruSeq = 0;
997
998    /**
999     * Keep track of the non-cached/empty process we last found, to help
1000     * determine how to distribute cached/empty processes next time.
1001     */
1002    int mNumNonCachedProcs = 0;
1003
1004    /**
1005     * Keep track of the number of cached hidden procs, to balance oom adj
1006     * distribution between those and empty procs.
1007     */
1008    int mNumCachedHiddenProcs = 0;
1009
1010    /**
1011     * Keep track of the number of service processes we last found, to
1012     * determine on the next iteration which should be B services.
1013     */
1014    int mNumServiceProcs = 0;
1015    int mNewNumAServiceProcs = 0;
1016    int mNewNumServiceProcs = 0;
1017
1018    /**
1019     * Allow the current computed overall memory level of the system to go down?
1020     * This is set to false when we are killing processes for reasons other than
1021     * memory management, so that the now smaller process list will not be taken as
1022     * an indication that memory is tighter.
1023     */
1024    boolean mAllowLowerMemLevel = false;
1025
1026    /**
1027     * The last computed memory level, for holding when we are in a state that
1028     * processes are going away for other reasons.
1029     */
1030    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1031
1032    /**
1033     * The last total number of process we have, to determine if changes actually look
1034     * like a shrinking number of process due to lower RAM.
1035     */
1036    int mLastNumProcesses;
1037
1038    /**
1039     * The uptime of the last time we performed idle maintenance.
1040     */
1041    long mLastIdleTime = SystemClock.uptimeMillis();
1042
1043    /**
1044     * Total time spent with RAM that has been added in the past since the last idle time.
1045     */
1046    long mLowRamTimeSinceLastIdle = 0;
1047
1048    /**
1049     * If RAM is currently low, when that horrible situation started.
1050     */
1051    long mLowRamStartTime = 0;
1052
1053    /**
1054     * For reporting to battery stats the current top application.
1055     */
1056    private String mCurResumedPackage = null;
1057    private int mCurResumedUid = -1;
1058
1059    /**
1060     * For reporting to battery stats the apps currently running foreground
1061     * service.  The ProcessMap is package/uid tuples; each of these contain
1062     * an array of the currently foreground processes.
1063     */
1064    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1065            = new ProcessMap<ArrayList<ProcessRecord>>();
1066
1067    /**
1068     * This is set if we had to do a delayed dexopt of an app before launching
1069     * it, to increase the ANR timeouts in that case.
1070     */
1071    boolean mDidDexOpt;
1072
1073    /**
1074     * Set if the systemServer made a call to enterSafeMode.
1075     */
1076    boolean mSafeMode;
1077
1078    /**
1079     * If true, we are running under a test environment so will sample PSS from processes
1080     * much more rapidly to try to collect better data when the tests are rapidly
1081     * running through apps.
1082     */
1083    boolean mTestPssMode = false;
1084
1085    String mDebugApp = null;
1086    boolean mWaitForDebugger = false;
1087    boolean mDebugTransient = false;
1088    String mOrigDebugApp = null;
1089    boolean mOrigWaitForDebugger = false;
1090    boolean mAlwaysFinishActivities = false;
1091    IActivityController mController = null;
1092    String mProfileApp = null;
1093    ProcessRecord mProfileProc = null;
1094    String mProfileFile;
1095    ParcelFileDescriptor mProfileFd;
1096    int mSamplingInterval = 0;
1097    boolean mAutoStopProfiler = false;
1098    int mProfileType = 0;
1099    String mOpenGlTraceApp = null;
1100
1101    final long[] mTmpLong = new long[1];
1102
1103    static class ProcessChangeItem {
1104        static final int CHANGE_ACTIVITIES = 1<<0;
1105        static final int CHANGE_PROCESS_STATE = 1<<1;
1106        int changes;
1107        int uid;
1108        int pid;
1109        int processState;
1110        boolean foregroundActivities;
1111    }
1112
1113    final RemoteCallbackList<IProcessObserver> mProcessObservers
1114            = new RemoteCallbackList<IProcessObserver>();
1115    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1116
1117    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1118            = new ArrayList<ProcessChangeItem>();
1119    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1120            = new ArrayList<ProcessChangeItem>();
1121
1122    /**
1123     * Runtime CPU use collection thread.  This object's lock is used to
1124     * perform synchronization with the thread (notifying it to run).
1125     */
1126    final Thread mProcessCpuThread;
1127
1128    /**
1129     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1130     * Must acquire this object's lock when accessing it.
1131     * NOTE: this lock will be held while doing long operations (trawling
1132     * through all processes in /proc), so it should never be acquired by
1133     * any critical paths such as when holding the main activity manager lock.
1134     */
1135    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1136            MONITOR_THREAD_CPU_USAGE);
1137    final AtomicLong mLastCpuTime = new AtomicLong(0);
1138    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1139
1140    long mLastWriteTime = 0;
1141
1142    /**
1143     * Used to retain an update lock when the foreground activity is in
1144     * immersive mode.
1145     */
1146    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1147
1148    /**
1149     * Set to true after the system has finished booting.
1150     */
1151    boolean mBooted = false;
1152
1153    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1154    int mProcessLimitOverride = -1;
1155
1156    WindowManagerService mWindowManager;
1157
1158    final ActivityThread mSystemThread;
1159
1160    // Holds the current foreground user's id
1161    int mCurrentUserId = 0;
1162    // Holds the target user's id during a user switch
1163    int mTargetUserId = UserHandle.USER_NULL;
1164    // If there are multiple profiles for the current user, their ids are here
1165    // Currently only the primary user can have managed profiles
1166    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1167
1168    /**
1169     * Mapping from each known user ID to the profile group ID it is associated with.
1170     */
1171    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1172
1173    private UserManagerService mUserManager;
1174
1175    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1176        final ProcessRecord mApp;
1177        final int mPid;
1178        final IApplicationThread mAppThread;
1179
1180        AppDeathRecipient(ProcessRecord app, int pid,
1181                IApplicationThread thread) {
1182            if (localLOGV) Slog.v(
1183                TAG, "New death recipient " + this
1184                + " for thread " + thread.asBinder());
1185            mApp = app;
1186            mPid = pid;
1187            mAppThread = thread;
1188        }
1189
1190        @Override
1191        public void binderDied() {
1192            if (localLOGV) Slog.v(
1193                TAG, "Death received in " + this
1194                + " for thread " + mAppThread.asBinder());
1195            synchronized(ActivityManagerService.this) {
1196                appDiedLocked(mApp, mPid, mAppThread);
1197            }
1198        }
1199    }
1200
1201    static final int SHOW_ERROR_MSG = 1;
1202    static final int SHOW_NOT_RESPONDING_MSG = 2;
1203    static final int SHOW_FACTORY_ERROR_MSG = 3;
1204    static final int UPDATE_CONFIGURATION_MSG = 4;
1205    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1206    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1207    static final int SERVICE_TIMEOUT_MSG = 12;
1208    static final int UPDATE_TIME_ZONE = 13;
1209    static final int SHOW_UID_ERROR_MSG = 14;
1210    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1211    static final int PROC_START_TIMEOUT_MSG = 20;
1212    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1213    static final int KILL_APPLICATION_MSG = 22;
1214    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1215    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1216    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1217    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1218    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1219    static final int CLEAR_DNS_CACHE_MSG = 28;
1220    static final int UPDATE_HTTP_PROXY_MSG = 29;
1221    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1222    static final int DISPATCH_PROCESSES_CHANGED = 31;
1223    static final int DISPATCH_PROCESS_DIED = 32;
1224    static final int REPORT_MEM_USAGE_MSG = 33;
1225    static final int REPORT_USER_SWITCH_MSG = 34;
1226    static final int CONTINUE_USER_SWITCH_MSG = 35;
1227    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1228    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1229    static final int PERSIST_URI_GRANTS_MSG = 38;
1230    static final int REQUEST_ALL_PSS_MSG = 39;
1231    static final int START_PROFILES_MSG = 40;
1232    static final int UPDATE_TIME = 41;
1233    static final int SYSTEM_USER_START_MSG = 42;
1234    static final int SYSTEM_USER_CURRENT_MSG = 43;
1235    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1236    static final int FINISH_BOOTING_MSG = 45;
1237    static final int START_USER_SWITCH_MSG = 46;
1238    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1239    static final int DISMISS_DIALOG_MSG = 48;
1240    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1241
1242    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1243    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1244    static final int FIRST_COMPAT_MODE_MSG = 300;
1245    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1246
1247    CompatModeDialog mCompatModeDialog;
1248    long mLastMemUsageReportTime = 0;
1249
1250    /**
1251     * Flag whether the current user is a "monkey", i.e. whether
1252     * the UI is driven by a UI automation tool.
1253     */
1254    private boolean mUserIsMonkey;
1255
1256    /** Flag whether the device has a Recents UI */
1257    boolean mHasRecents;
1258
1259    /** The dimensions of the thumbnails in the Recents UI. */
1260    int mThumbnailWidth;
1261    int mThumbnailHeight;
1262
1263    final ServiceThread mHandlerThread;
1264    final MainHandler mHandler;
1265
1266    final class MainHandler extends Handler {
1267        public MainHandler(Looper looper) {
1268            super(looper, null, true);
1269        }
1270
1271        @Override
1272        public void handleMessage(Message msg) {
1273            switch (msg.what) {
1274            case SHOW_ERROR_MSG: {
1275                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1277                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1278                synchronized (ActivityManagerService.this) {
1279                    ProcessRecord proc = (ProcessRecord)data.get("app");
1280                    AppErrorResult res = (AppErrorResult) data.get("result");
1281                    if (proc != null && proc.crashDialog != null) {
1282                        Slog.e(TAG, "App already has crash dialog: " + proc);
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                        return;
1287                    }
1288                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1289                            >= Process.FIRST_APPLICATION_UID
1290                            && proc.pid != MY_PID);
1291                    for (int userId : mCurrentProfileIds) {
1292                        isBackground &= (proc.userId != userId);
1293                    }
1294                    if (isBackground && !showBackground) {
1295                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1296                        if (res != null) {
1297                            res.set(0);
1298                        }
1299                        return;
1300                    }
1301                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1302                        Dialog d = new AppErrorDialog(mContext,
1303                                ActivityManagerService.this, res, proc);
1304                        d.show();
1305                        proc.crashDialog = d;
1306                    } else {
1307                        // The device is asleep, so just pretend that the user
1308                        // saw a crash dialog and hit "force quit".
1309                        if (res != null) {
1310                            res.set(0);
1311                        }
1312                    }
1313                }
1314
1315                ensureBootCompleted();
1316            } break;
1317            case SHOW_NOT_RESPONDING_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                    ProcessRecord proc = (ProcessRecord)data.get("app");
1321                    if (proc != null && proc.anrDialog != null) {
1322                        Slog.e(TAG, "App already has anr dialog: " + proc);
1323                        return;
1324                    }
1325
1326                    Intent intent = new Intent("android.intent.action.ANR");
1327                    if (!mProcessesReady) {
1328                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1329                                | Intent.FLAG_RECEIVER_FOREGROUND);
1330                    }
1331                    broadcastIntentLocked(null, null, intent,
1332                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1333                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1334
1335                    if (mShowDialogs) {
1336                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1337                                mContext, proc, (ActivityRecord)data.get("activity"),
1338                                msg.arg1 != 0);
1339                        d.show();
1340                        proc.anrDialog = d;
1341                    } else {
1342                        // Just kill the app if there is no dialog to be shown.
1343                        killAppAtUsersRequest(proc, null);
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1350                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord proc = (ProcessRecord) data.get("app");
1353                    if (proc == null) {
1354                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1355                        break;
1356                    }
1357                    if (proc.crashDialog != null) {
1358                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1359                        return;
1360                    }
1361                    AppErrorResult res = (AppErrorResult) data.get("result");
1362                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1363                        Dialog d = new StrictModeViolationDialog(mContext,
1364                                ActivityManagerService.this, res, proc);
1365                        d.show();
1366                        proc.crashDialog = d;
1367                    } else {
1368                        // The device is asleep, so just pretend that the user
1369                        // saw a crash dialog and hit "force quit".
1370                        res.set(0);
1371                    }
1372                }
1373                ensureBootCompleted();
1374            } break;
1375            case SHOW_FACTORY_ERROR_MSG: {
1376                Dialog d = new FactoryErrorDialog(
1377                    mContext, msg.getData().getCharSequence("msg"));
1378                d.show();
1379                ensureBootCompleted();
1380            } break;
1381            case UPDATE_CONFIGURATION_MSG: {
1382                final ContentResolver resolver = mContext.getContentResolver();
1383                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1384            } break;
1385            case GC_BACKGROUND_PROCESSES_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    performAppGcsIfAppropriateLocked();
1388                }
1389            } break;
1390            case WAIT_FOR_DEBUGGER_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    ProcessRecord app = (ProcessRecord)msg.obj;
1393                    if (msg.arg1 != 0) {
1394                        if (!app.waitedForDebugger) {
1395                            Dialog d = new AppWaitingForDebuggerDialog(
1396                                    ActivityManagerService.this,
1397                                    mContext, app);
1398                            app.waitDialog = d;
1399                            app.waitedForDebugger = true;
1400                            d.show();
1401                        }
1402                    } else {
1403                        if (app.waitDialog != null) {
1404                            app.waitDialog.dismiss();
1405                            app.waitDialog = null;
1406                        }
1407                    }
1408                }
1409            } break;
1410            case SERVICE_TIMEOUT_MSG: {
1411                if (mDidDexOpt) {
1412                    mDidDexOpt = false;
1413                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1414                    nmsg.obj = msg.obj;
1415                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1416                    return;
1417                }
1418                mServices.serviceTimeout((ProcessRecord)msg.obj);
1419            } break;
1420            case UPDATE_TIME_ZONE: {
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.updateTimeZone();
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case CLEAR_DNS_CACHE_MSG: {
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.clearDnsCache();
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case UPDATE_HTTP_PROXY_MSG: {
1449                ProxyInfo proxy = (ProxyInfo)msg.obj;
1450                String host = "";
1451                String port = "";
1452                String exclList = "";
1453                Uri pacFileUrl = Uri.EMPTY;
1454                if (proxy != null) {
1455                    host = proxy.getHost();
1456                    port = Integer.toString(proxy.getPort());
1457                    exclList = proxy.getExclusionListAsString();
1458                    pacFileUrl = proxy.getPacFileUrl();
1459                }
1460                synchronized (ActivityManagerService.this) {
1461                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                        ProcessRecord r = mLruProcesses.get(i);
1463                        if (r.thread != null) {
1464                            try {
1465                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1466                            } catch (RemoteException ex) {
1467                                Slog.w(TAG, "Failed to update http proxy for: " +
1468                                        r.info.processName);
1469                            }
1470                        }
1471                    }
1472                }
1473            } break;
1474            case SHOW_UID_ERROR_MSG: {
1475                if (mShowDialogs) {
1476                    AlertDialog d = new BaseErrorDialog(mContext);
1477                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1478                    d.setCancelable(false);
1479                    d.setTitle(mContext.getText(R.string.android_system_label));
1480                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1481                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1482                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1483                    d.show();
1484                }
1485            } break;
1486            case SHOW_FINGERPRINT_ERROR_MSG: {
1487                if (mShowDialogs) {
1488                    AlertDialog d = new BaseErrorDialog(mContext);
1489                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1490                    d.setCancelable(false);
1491                    d.setTitle(mContext.getText(R.string.android_system_label));
1492                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1493                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1494                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1495                    d.show();
1496                }
1497            } break;
1498            case PROC_START_TIMEOUT_MSG: {
1499                if (mDidDexOpt) {
1500                    mDidDexOpt = false;
1501                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1502                    nmsg.obj = msg.obj;
1503                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1504                    return;
1505                }
1506                ProcessRecord app = (ProcessRecord)msg.obj;
1507                synchronized (ActivityManagerService.this) {
1508                    processStartTimedOutLocked(app);
1509                }
1510            } break;
1511            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1514                }
1515            } break;
1516            case KILL_APPLICATION_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    int appid = msg.arg1;
1519                    boolean restart = (msg.arg2 == 1);
1520                    Bundle bundle = (Bundle)msg.obj;
1521                    String pkg = bundle.getString("pkg");
1522                    String reason = bundle.getString("reason");
1523                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1524                            false, UserHandle.USER_ALL, reason);
1525                }
1526            } break;
1527            case FINALIZE_PENDING_INTENT_MSG: {
1528                ((PendingIntentRecord)msg.obj).completeFinalize();
1529            } break;
1530            case POST_HEAVY_NOTIFICATION_MSG: {
1531                INotificationManager inm = NotificationManager.getService();
1532                if (inm == null) {
1533                    return;
1534                }
1535
1536                ActivityRecord root = (ActivityRecord)msg.obj;
1537                ProcessRecord process = root.app;
1538                if (process == null) {
1539                    return;
1540                }
1541
1542                try {
1543                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1544                    String text = mContext.getString(R.string.heavy_weight_notification,
1545                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1546                    Notification notification = new Notification();
1547                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1548                    notification.when = 0;
1549                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1550                    notification.tickerText = text;
1551                    notification.defaults = 0; // please be quiet
1552                    notification.sound = null;
1553                    notification.vibrate = null;
1554                    notification.color = mContext.getResources().getColor(
1555                            com.android.internal.R.color.system_notification_accent_color);
1556                    notification.setLatestEventInfo(context, text,
1557                            mContext.getText(R.string.heavy_weight_notification_detail),
1558                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1559                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1560                                    new UserHandle(root.userId)));
1561
1562                    try {
1563                        int[] outId = new int[1];
1564                        inm.enqueueNotificationWithTag("android", "android", null,
1565                                R.string.heavy_weight_notification,
1566                                notification, outId, root.userId);
1567                    } catch (RuntimeException e) {
1568                        Slog.w(ActivityManagerService.TAG,
1569                                "Error showing notification for heavy-weight app", e);
1570                    } catch (RemoteException e) {
1571                    }
1572                } catch (NameNotFoundException e) {
1573                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1574                }
1575            } break;
1576            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1577                INotificationManager inm = NotificationManager.getService();
1578                if (inm == null) {
1579                    return;
1580                }
1581                try {
1582                    inm.cancelNotificationWithTag("android", null,
1583                            R.string.heavy_weight_notification,  msg.arg1);
1584                } catch (RuntimeException e) {
1585                    Slog.w(ActivityManagerService.TAG,
1586                            "Error canceling notification for service", e);
1587                } catch (RemoteException e) {
1588                }
1589            } break;
1590            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1591                synchronized (ActivityManagerService.this) {
1592                    checkExcessivePowerUsageLocked(true);
1593                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1594                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1595                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1596                }
1597            } break;
1598            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1599                synchronized (ActivityManagerService.this) {
1600                    ActivityRecord ar = (ActivityRecord)msg.obj;
1601                    if (mCompatModeDialog != null) {
1602                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1603                                ar.info.applicationInfo.packageName)) {
1604                            return;
1605                        }
1606                        mCompatModeDialog.dismiss();
1607                        mCompatModeDialog = null;
1608                    }
1609                    if (ar != null && false) {
1610                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1611                                ar.packageName)) {
1612                            int mode = mCompatModePackages.computeCompatModeLocked(
1613                                    ar.info.applicationInfo);
1614                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1615                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1616                                mCompatModeDialog = new CompatModeDialog(
1617                                        ActivityManagerService.this, mContext,
1618                                        ar.info.applicationInfo);
1619                                mCompatModeDialog.show();
1620                            }
1621                        }
1622                    }
1623                }
1624                break;
1625            }
1626            case DISPATCH_PROCESSES_CHANGED: {
1627                dispatchProcessesChanged();
1628                break;
1629            }
1630            case DISPATCH_PROCESS_DIED: {
1631                final int pid = msg.arg1;
1632                final int uid = msg.arg2;
1633                dispatchProcessDied(pid, uid);
1634                break;
1635            }
1636            case REPORT_MEM_USAGE_MSG: {
1637                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1638                Thread thread = new Thread() {
1639                    @Override public void run() {
1640                        reportMemUsage(memInfos);
1641                    }
1642                };
1643                thread.start();
1644                break;
1645            }
1646            case START_USER_SWITCH_MSG: {
1647                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1648                break;
1649            }
1650            case REPORT_USER_SWITCH_MSG: {
1651                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case CONTINUE_USER_SWITCH_MSG: {
1655                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case USER_SWITCH_TIMEOUT_MSG: {
1659                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case IMMERSIVE_MODE_LOCK_MSG: {
1663                final boolean nextState = (msg.arg1 != 0);
1664                if (mUpdateLock.isHeld() != nextState) {
1665                    if (DEBUG_IMMERSIVE) {
1666                        final ActivityRecord r = (ActivityRecord) msg.obj;
1667                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1668                    }
1669                    if (nextState) {
1670                        mUpdateLock.acquire();
1671                    } else {
1672                        mUpdateLock.release();
1673                    }
1674                }
1675                break;
1676            }
1677            case PERSIST_URI_GRANTS_MSG: {
1678                writeGrantedUriPermissions();
1679                break;
1680            }
1681            case REQUEST_ALL_PSS_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1684                }
1685                break;
1686            }
1687            case START_PROFILES_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    startProfilesLocked();
1690                }
1691                break;
1692            }
1693            case UPDATE_TIME: {
1694                synchronized (ActivityManagerService.this) {
1695                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1696                        ProcessRecord r = mLruProcesses.get(i);
1697                        if (r.thread != null) {
1698                            try {
1699                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1700                            } catch (RemoteException ex) {
1701                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1702                            }
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case SYSTEM_USER_START_MSG: {
1709                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.startUser(msg.arg1);
1712                break;
1713            }
1714            case SYSTEM_USER_CURRENT_MSG: {
1715                mBatteryStatsService.noteEvent(
1716                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1717                        Integer.toString(msg.arg2), msg.arg2);
1718                mBatteryStatsService.noteEvent(
1719                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1720                        Integer.toString(msg.arg1), msg.arg1);
1721                mSystemServiceManager.switchUser(msg.arg1);
1722                break;
1723            }
1724            case ENTER_ANIMATION_COMPLETE_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1727                    if (r != null && r.app != null && r.app.thread != null) {
1728                        try {
1729                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1730                        } catch (RemoteException e) {
1731                        }
1732                    }
1733                }
1734                break;
1735            }
1736            case FINISH_BOOTING_MSG: {
1737                if (msg.arg1 != 0) {
1738                    finishBooting();
1739                }
1740                if (msg.arg2 != 0) {
1741                    enableScreenAfterBoot();
1742                }
1743                break;
1744            }
1745            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1746                try {
1747                    Locale l = (Locale) msg.obj;
1748                    IBinder service = ServiceManager.getService("mount");
1749                    IMountService mountService = IMountService.Stub.asInterface(service);
1750                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1751                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1752                } catch (RemoteException e) {
1753                    Log.e(TAG, "Error storing locale for decryption UI", e);
1754                }
1755                break;
1756            }
1757            case DISMISS_DIALOG_MSG: {
1758                final Dialog d = (Dialog) msg.obj;
1759                d.dismiss();
1760                break;
1761            }
1762            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    int i = mTaskStackListeners.beginBroadcast();
1765                    while (i > 0) {
1766                        i--;
1767                        try {
1768                            // Make a one-way callback to the listener
1769                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1770                        } catch (RemoteException e){
1771                            // Handled by the RemoteCallbackList
1772                        }
1773                    }
1774                    mTaskStackListeners.finishBroadcast();
1775                }
1776                break;
1777            }
1778            }
1779        }
1780    };
1781
1782    static final int COLLECT_PSS_BG_MSG = 1;
1783
1784    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case COLLECT_PSS_BG_MSG: {
1789                long start = SystemClock.uptimeMillis();
1790                MemInfoReader memInfo = null;
1791                synchronized (ActivityManagerService.this) {
1792                    if (mFullPssPending) {
1793                        mFullPssPending = false;
1794                        memInfo = new MemInfoReader();
1795                    }
1796                }
1797                if (memInfo != null) {
1798                    updateCpuStatsNow();
1799                    long nativeTotalPss = 0;
1800                    synchronized (mProcessCpuTracker) {
1801                        final int N = mProcessCpuTracker.countStats();
1802                        for (int j=0; j<N; j++) {
1803                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1804                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1805                                // This is definitely an application process; skip it.
1806                                continue;
1807                            }
1808                            synchronized (mPidsSelfLocked) {
1809                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1810                                    // This is one of our own processes; skip it.
1811                                    continue;
1812                                }
1813                            }
1814                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1815                        }
1816                    }
1817                    memInfo.readMemInfo();
1818                    synchronized (ActivityManagerService.this) {
1819                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1820                                + (SystemClock.uptimeMillis()-start) + "ms");
1821                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1822                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1823                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1824                    }
1825                }
1826
1827                int num = 0;
1828                long[] tmp = new long[1];
1829                do {
1830                    ProcessRecord proc;
1831                    int procState;
1832                    int pid;
1833                    long lastPssTime;
1834                    synchronized (ActivityManagerService.this) {
1835                        if (mPendingPssProcesses.size() <= 0) {
1836                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1837                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1838                            mPendingPssProcesses.clear();
1839                            return;
1840                        }
1841                        proc = mPendingPssProcesses.remove(0);
1842                        procState = proc.pssProcState;
1843                        lastPssTime = proc.lastPssTime;
1844                        if (proc.thread != null && procState == proc.setProcState) {
1845                            pid = proc.pid;
1846                        } else {
1847                            proc = null;
1848                            pid = 0;
1849                        }
1850                    }
1851                    if (proc != null) {
1852                        long pss = Debug.getPss(pid, tmp, null);
1853                        synchronized (ActivityManagerService.this) {
1854                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1855                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1856                                num++;
1857                                recordPssSample(proc, procState, pss, tmp[0],
1858                                        SystemClock.uptimeMillis());
1859                            }
1860                        }
1861                    }
1862                } while (true);
1863            }
1864            }
1865        }
1866    };
1867
1868    public void setSystemProcess() {
1869        try {
1870            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1871            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1872            ServiceManager.addService("meminfo", new MemBinder(this));
1873            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1874            ServiceManager.addService("dbinfo", new DbBinder(this));
1875            if (MONITOR_CPU_USAGE) {
1876                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1877            }
1878            ServiceManager.addService("permission", new PermissionController(this));
1879
1880            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1881                    "android", STOCK_PM_FLAGS);
1882            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1883
1884            synchronized (this) {
1885                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1886                app.persistent = true;
1887                app.pid = MY_PID;
1888                app.maxAdj = ProcessList.SYSTEM_ADJ;
1889                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1890                mProcessNames.put(app.processName, app.uid, app);
1891                synchronized (mPidsSelfLocked) {
1892                    mPidsSelfLocked.put(app.pid, app);
1893                }
1894                updateLruProcessLocked(app, false, null);
1895                updateOomAdjLocked();
1896            }
1897        } catch (PackageManager.NameNotFoundException e) {
1898            throw new RuntimeException(
1899                    "Unable to find android system package", e);
1900        }
1901    }
1902
1903    public void setWindowManager(WindowManagerService wm) {
1904        mWindowManager = wm;
1905        mStackSupervisor.setWindowManager(wm);
1906    }
1907
1908    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1909        mUsageStatsService = usageStatsManager;
1910    }
1911
1912    public void startObservingNativeCrashes() {
1913        final NativeCrashListener ncl = new NativeCrashListener(this);
1914        ncl.start();
1915    }
1916
1917    public IAppOpsService getAppOpsService() {
1918        return mAppOpsService;
1919    }
1920
1921    static class MemBinder extends Binder {
1922        ActivityManagerService mActivityManagerService;
1923        MemBinder(ActivityManagerService activityManagerService) {
1924            mActivityManagerService = activityManagerService;
1925        }
1926
1927        @Override
1928        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1929            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1930                    != PackageManager.PERMISSION_GRANTED) {
1931                pw.println("Permission Denial: can't dump meminfo from from pid="
1932                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1933                        + " without permission " + android.Manifest.permission.DUMP);
1934                return;
1935            }
1936
1937            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1938        }
1939    }
1940
1941    static class GraphicsBinder extends Binder {
1942        ActivityManagerService mActivityManagerService;
1943        GraphicsBinder(ActivityManagerService activityManagerService) {
1944            mActivityManagerService = activityManagerService;
1945        }
1946
1947        @Override
1948        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1949            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1950                    != PackageManager.PERMISSION_GRANTED) {
1951                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1952                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1953                        + " without permission " + android.Manifest.permission.DUMP);
1954                return;
1955            }
1956
1957            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1958        }
1959    }
1960
1961    static class DbBinder extends Binder {
1962        ActivityManagerService mActivityManagerService;
1963        DbBinder(ActivityManagerService activityManagerService) {
1964            mActivityManagerService = activityManagerService;
1965        }
1966
1967        @Override
1968        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1969            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1970                    != PackageManager.PERMISSION_GRANTED) {
1971                pw.println("Permission Denial: can't dump dbinfo from from pid="
1972                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1973                        + " without permission " + android.Manifest.permission.DUMP);
1974                return;
1975            }
1976
1977            mActivityManagerService.dumpDbInfo(fd, pw, args);
1978        }
1979    }
1980
1981    static class CpuBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        CpuBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            synchronized (mActivityManagerService.mProcessCpuTracker) {
1998                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1999                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2000                        SystemClock.uptimeMillis()));
2001            }
2002        }
2003    }
2004
2005    public static final class Lifecycle extends SystemService {
2006        private final ActivityManagerService mService;
2007
2008        public Lifecycle(Context context) {
2009            super(context);
2010            mService = new ActivityManagerService(context);
2011        }
2012
2013        @Override
2014        public void onStart() {
2015            mService.start();
2016        }
2017
2018        public ActivityManagerService getService() {
2019            return mService;
2020        }
2021    }
2022
2023    // Note: This method is invoked on the main thread but may need to attach various
2024    // handlers to other threads.  So take care to be explicit about the looper.
2025    public ActivityManagerService(Context systemContext) {
2026        mContext = systemContext;
2027        mFactoryTest = FactoryTest.getMode();
2028        mSystemThread = ActivityThread.currentActivityThread();
2029
2030        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2031
2032        mHandlerThread = new ServiceThread(TAG,
2033                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2034        mHandlerThread.start();
2035        mHandler = new MainHandler(mHandlerThread.getLooper());
2036
2037        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "foreground", BROADCAST_FG_TIMEOUT, false);
2039        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "background", BROADCAST_BG_TIMEOUT, true);
2041        mBroadcastQueues[0] = mFgBroadcastQueue;
2042        mBroadcastQueues[1] = mBgBroadcastQueue;
2043
2044        mServices = new ActiveServices(this);
2045        mProviderMap = new ProviderMap(this);
2046
2047        // TODO: Move creation of battery stats service outside of activity manager service.
2048        File dataDir = Environment.getDataDirectory();
2049        File systemDir = new File(dataDir, "system");
2050        systemDir.mkdirs();
2051        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2052        mBatteryStatsService.getActiveStatistics().readLocked();
2053        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2054        mOnBattery = DEBUG_POWER ? true
2055                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2056        mBatteryStatsService.getActiveStatistics().setCallback(this);
2057
2058        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2059
2060        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2061
2062        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2063
2064        // User 0 is the first and only user that runs at boot.
2065        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2066        mUserLru.add(Integer.valueOf(0));
2067        updateStartedUserArrayLocked();
2068
2069        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2070            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2071
2072        mConfiguration.setToDefaults();
2073        mConfiguration.setLocale(Locale.getDefault());
2074
2075        mConfigurationSeq = mConfiguration.seq = 1;
2076        mProcessCpuTracker.init();
2077
2078        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2079        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2080        mStackSupervisor = new ActivityStackSupervisor(this);
2081        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2082
2083        mProcessCpuThread = new Thread("CpuTracker") {
2084            @Override
2085            public void run() {
2086                while (true) {
2087                    try {
2088                        try {
2089                            synchronized(this) {
2090                                final long now = SystemClock.uptimeMillis();
2091                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2092                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2093                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2094                                //        + ", write delay=" + nextWriteDelay);
2095                                if (nextWriteDelay < nextCpuDelay) {
2096                                    nextCpuDelay = nextWriteDelay;
2097                                }
2098                                if (nextCpuDelay > 0) {
2099                                    mProcessCpuMutexFree.set(true);
2100                                    this.wait(nextCpuDelay);
2101                                }
2102                            }
2103                        } catch (InterruptedException e) {
2104                        }
2105                        updateCpuStatsNow();
2106                    } catch (Exception e) {
2107                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2108                    }
2109                }
2110            }
2111        };
2112
2113        Watchdog.getInstance().addMonitor(this);
2114        Watchdog.getInstance().addThread(mHandler);
2115    }
2116
2117    public void setSystemServiceManager(SystemServiceManager mgr) {
2118        mSystemServiceManager = mgr;
2119    }
2120
2121    public void setInstaller(Installer installer) {
2122        mInstaller = installer;
2123    }
2124
2125    private void start() {
2126        Process.removeAllProcessGroups();
2127        mProcessCpuThread.start();
2128
2129        mBatteryStatsService.publish(mContext);
2130        mAppOpsService.publish(mContext);
2131        Slog.d("AppOps", "AppOpsService published");
2132        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2133    }
2134
2135    public void initPowerManagement() {
2136        mStackSupervisor.initPowerManagement();
2137        mBatteryStatsService.initPowerManagement();
2138    }
2139
2140    @Override
2141    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2142            throws RemoteException {
2143        if (code == SYSPROPS_TRANSACTION) {
2144            // We need to tell all apps about the system property change.
2145            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2146            synchronized(this) {
2147                final int NP = mProcessNames.getMap().size();
2148                for (int ip=0; ip<NP; ip++) {
2149                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2150                    final int NA = apps.size();
2151                    for (int ia=0; ia<NA; ia++) {
2152                        ProcessRecord app = apps.valueAt(ia);
2153                        if (app.thread != null) {
2154                            procs.add(app.thread.asBinder());
2155                        }
2156                    }
2157                }
2158            }
2159
2160            int N = procs.size();
2161            for (int i=0; i<N; i++) {
2162                Parcel data2 = Parcel.obtain();
2163                try {
2164                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2165                } catch (RemoteException e) {
2166                }
2167                data2.recycle();
2168            }
2169        }
2170        try {
2171            return super.onTransact(code, data, reply, flags);
2172        } catch (RuntimeException e) {
2173            // The activity manager only throws security exceptions, so let's
2174            // log all others.
2175            if (!(e instanceof SecurityException)) {
2176                Slog.wtf(TAG, "Activity Manager Crash", e);
2177            }
2178            throw e;
2179        }
2180    }
2181
2182    void updateCpuStats() {
2183        final long now = SystemClock.uptimeMillis();
2184        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2185            return;
2186        }
2187        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2188            synchronized (mProcessCpuThread) {
2189                mProcessCpuThread.notify();
2190            }
2191        }
2192    }
2193
2194    void updateCpuStatsNow() {
2195        synchronized (mProcessCpuTracker) {
2196            mProcessCpuMutexFree.set(false);
2197            final long now = SystemClock.uptimeMillis();
2198            boolean haveNewCpuStats = false;
2199
2200            if (MONITOR_CPU_USAGE &&
2201                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2202                mLastCpuTime.set(now);
2203                haveNewCpuStats = true;
2204                mProcessCpuTracker.update();
2205                //Slog.i(TAG, mProcessCpu.printCurrentState());
2206                //Slog.i(TAG, "Total CPU usage: "
2207                //        + mProcessCpu.getTotalCpuPercent() + "%");
2208
2209                // Slog the cpu usage if the property is set.
2210                if ("true".equals(SystemProperties.get("events.cpu"))) {
2211                    int user = mProcessCpuTracker.getLastUserTime();
2212                    int system = mProcessCpuTracker.getLastSystemTime();
2213                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2214                    int irq = mProcessCpuTracker.getLastIrqTime();
2215                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2216                    int idle = mProcessCpuTracker.getLastIdleTime();
2217
2218                    int total = user + system + iowait + irq + softIrq + idle;
2219                    if (total == 0) total = 1;
2220
2221                    EventLog.writeEvent(EventLogTags.CPU,
2222                            ((user+system+iowait+irq+softIrq) * 100) / total,
2223                            (user * 100) / total,
2224                            (system * 100) / total,
2225                            (iowait * 100) / total,
2226                            (irq * 100) / total,
2227                            (softIrq * 100) / total);
2228                }
2229            }
2230
2231            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2232            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2233            synchronized(bstats) {
2234                synchronized(mPidsSelfLocked) {
2235                    if (haveNewCpuStats) {
2236                        if (mOnBattery) {
2237                            int perc = bstats.startAddingCpuLocked();
2238                            int totalUTime = 0;
2239                            int totalSTime = 0;
2240                            final int N = mProcessCpuTracker.countStats();
2241                            for (int i=0; i<N; i++) {
2242                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2243                                if (!st.working) {
2244                                    continue;
2245                                }
2246                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2247                                int otherUTime = (st.rel_utime*perc)/100;
2248                                int otherSTime = (st.rel_stime*perc)/100;
2249                                totalUTime += otherUTime;
2250                                totalSTime += otherSTime;
2251                                if (pr != null) {
2252                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2253                                    if (ps == null || !ps.isActive()) {
2254                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2255                                                pr.info.uid, pr.processName);
2256                                    }
2257                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2258                                            st.rel_stime-otherSTime);
2259                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2260                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2261                                } else {
2262                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2263                                    if (ps == null || !ps.isActive()) {
2264                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2265                                                bstats.mapUid(st.uid), st.name);
2266                                    }
2267                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2268                                            st.rel_stime-otherSTime);
2269                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2270                                }
2271                            }
2272                            bstats.finishAddingCpuLocked(perc, totalUTime,
2273                                    totalSTime, cpuSpeedTimes);
2274                        }
2275                    }
2276                }
2277
2278                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2279                    mLastWriteTime = now;
2280                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2281                }
2282            }
2283        }
2284    }
2285
2286    @Override
2287    public void batteryNeedsCpuUpdate() {
2288        updateCpuStatsNow();
2289    }
2290
2291    @Override
2292    public void batteryPowerChanged(boolean onBattery) {
2293        // When plugging in, update the CPU stats first before changing
2294        // the plug state.
2295        updateCpuStatsNow();
2296        synchronized (this) {
2297            synchronized(mPidsSelfLocked) {
2298                mOnBattery = DEBUG_POWER ? true : onBattery;
2299            }
2300        }
2301    }
2302
2303    /**
2304     * Initialize the application bind args. These are passed to each
2305     * process when the bindApplication() IPC is sent to the process. They're
2306     * lazily setup to make sure the services are running when they're asked for.
2307     */
2308    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2309        if (mAppBindArgs == null) {
2310            mAppBindArgs = new HashMap<>();
2311
2312            // Isolated processes won't get this optimization, so that we don't
2313            // violate the rules about which services they have access to.
2314            if (!isolated) {
2315                // Setup the application init args
2316                mAppBindArgs.put("package", ServiceManager.getService("package"));
2317                mAppBindArgs.put("window", ServiceManager.getService("window"));
2318                mAppBindArgs.put(Context.ALARM_SERVICE,
2319                        ServiceManager.getService(Context.ALARM_SERVICE));
2320            }
2321        }
2322        return mAppBindArgs;
2323    }
2324
2325    final void setFocusedActivityLocked(ActivityRecord r) {
2326        if (mFocusedActivity != r) {
2327            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2328            mFocusedActivity = r;
2329            if (r.task != null && r.task.voiceInteractor != null) {
2330                startRunningVoiceLocked();
2331            } else {
2332                finishRunningVoiceLocked();
2333            }
2334            mStackSupervisor.setFocusedStack(r);
2335            if (r != null) {
2336                mWindowManager.setFocusedApp(r.appToken, true);
2337            }
2338            applyUpdateLockStateLocked(r);
2339        }
2340    }
2341
2342    final void clearFocusedActivity(ActivityRecord r) {
2343        if (mFocusedActivity == r) {
2344            mFocusedActivity = null;
2345        }
2346    }
2347
2348    @Override
2349    public void setFocusedStack(int stackId) {
2350        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2351        synchronized (ActivityManagerService.this) {
2352            ActivityStack stack = mStackSupervisor.getStack(stackId);
2353            if (stack != null) {
2354                ActivityRecord r = stack.topRunningActivityLocked(null);
2355                if (r != null) {
2356                    setFocusedActivityLocked(r);
2357                }
2358            }
2359        }
2360    }
2361
2362    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2363    @Override
2364    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2365        synchronized (ActivityManagerService.this) {
2366            if (listener != null) {
2367                mTaskStackListeners.register(listener);
2368            }
2369        }
2370    }
2371
2372    @Override
2373    public void notifyActivityDrawn(IBinder token) {
2374        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2375        synchronized (this) {
2376            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2377            if (r != null) {
2378                r.task.stack.notifyActivityDrawnLocked(r);
2379            }
2380        }
2381    }
2382
2383    final void applyUpdateLockStateLocked(ActivityRecord r) {
2384        // Modifications to the UpdateLock state are done on our handler, outside
2385        // the activity manager's locks.  The new state is determined based on the
2386        // state *now* of the relevant activity record.  The object is passed to
2387        // the handler solely for logging detail, not to be consulted/modified.
2388        final boolean nextState = r != null && r.immersive;
2389        mHandler.sendMessage(
2390                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2391    }
2392
2393    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2394        Message msg = Message.obtain();
2395        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2396        msg.obj = r.task.askedCompatMode ? null : r;
2397        mHandler.sendMessage(msg);
2398    }
2399
2400    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2401            String what, Object obj, ProcessRecord srcApp) {
2402        app.lastActivityTime = now;
2403
2404        if (app.activities.size() > 0) {
2405            // Don't want to touch dependent processes that are hosting activities.
2406            return index;
2407        }
2408
2409        int lrui = mLruProcesses.lastIndexOf(app);
2410        if (lrui < 0) {
2411            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2412                    + what + " " + obj + " from " + srcApp);
2413            return index;
2414        }
2415
2416        if (lrui >= index) {
2417            // Don't want to cause this to move dependent processes *back* in the
2418            // list as if they were less frequently used.
2419            return index;
2420        }
2421
2422        if (lrui >= mLruProcessActivityStart) {
2423            // Don't want to touch dependent processes that are hosting activities.
2424            return index;
2425        }
2426
2427        mLruProcesses.remove(lrui);
2428        if (index > 0) {
2429            index--;
2430        }
2431        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2432                + " in LRU list: " + app);
2433        mLruProcesses.add(index, app);
2434        return index;
2435    }
2436
2437    final void removeLruProcessLocked(ProcessRecord app) {
2438        int lrui = mLruProcesses.lastIndexOf(app);
2439        if (lrui >= 0) {
2440            if (!app.killed) {
2441                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2442                Process.killProcessQuiet(app.pid);
2443                Process.killProcessGroup(app.info.uid, app.pid);
2444            }
2445            if (lrui <= mLruProcessActivityStart) {
2446                mLruProcessActivityStart--;
2447            }
2448            if (lrui <= mLruProcessServiceStart) {
2449                mLruProcessServiceStart--;
2450            }
2451            mLruProcesses.remove(lrui);
2452        }
2453    }
2454
2455    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2456            ProcessRecord client) {
2457        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2458                || app.treatLikeActivity;
2459        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2460        if (!activityChange && hasActivity) {
2461            // The process has activities, so we are only allowing activity-based adjustments
2462            // to move it.  It should be kept in the front of the list with other
2463            // processes that have activities, and we don't want those to change their
2464            // order except due to activity operations.
2465            return;
2466        }
2467
2468        mLruSeq++;
2469        final long now = SystemClock.uptimeMillis();
2470        app.lastActivityTime = now;
2471
2472        // First a quick reject: if the app is already at the position we will
2473        // put it, then there is nothing to do.
2474        if (hasActivity) {
2475            final int N = mLruProcesses.size();
2476            if (N > 0 && mLruProcesses.get(N-1) == app) {
2477                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2478                return;
2479            }
2480        } else {
2481            if (mLruProcessServiceStart > 0
2482                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2483                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2484                return;
2485            }
2486        }
2487
2488        int lrui = mLruProcesses.lastIndexOf(app);
2489
2490        if (app.persistent && lrui >= 0) {
2491            // We don't care about the position of persistent processes, as long as
2492            // they are in the list.
2493            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2494            return;
2495        }
2496
2497        /* In progress: compute new position first, so we can avoid doing work
2498           if the process is not actually going to move.  Not yet working.
2499        int addIndex;
2500        int nextIndex;
2501        boolean inActivity = false, inService = false;
2502        if (hasActivity) {
2503            // Process has activities, put it at the very tipsy-top.
2504            addIndex = mLruProcesses.size();
2505            nextIndex = mLruProcessServiceStart;
2506            inActivity = true;
2507        } else if (hasService) {
2508            // Process has services, put it at the top of the service list.
2509            addIndex = mLruProcessActivityStart;
2510            nextIndex = mLruProcessServiceStart;
2511            inActivity = true;
2512            inService = true;
2513        } else  {
2514            // Process not otherwise of interest, it goes to the top of the non-service area.
2515            addIndex = mLruProcessServiceStart;
2516            if (client != null) {
2517                int clientIndex = mLruProcesses.lastIndexOf(client);
2518                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2519                        + app);
2520                if (clientIndex >= 0 && addIndex > clientIndex) {
2521                    addIndex = clientIndex;
2522                }
2523            }
2524            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2525        }
2526
2527        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2528                + mLruProcessActivityStart + "): " + app);
2529        */
2530
2531        if (lrui >= 0) {
2532            if (lrui < mLruProcessActivityStart) {
2533                mLruProcessActivityStart--;
2534            }
2535            if (lrui < mLruProcessServiceStart) {
2536                mLruProcessServiceStart--;
2537            }
2538            /*
2539            if (addIndex > lrui) {
2540                addIndex--;
2541            }
2542            if (nextIndex > lrui) {
2543                nextIndex--;
2544            }
2545            */
2546            mLruProcesses.remove(lrui);
2547        }
2548
2549        /*
2550        mLruProcesses.add(addIndex, app);
2551        if (inActivity) {
2552            mLruProcessActivityStart++;
2553        }
2554        if (inService) {
2555            mLruProcessActivityStart++;
2556        }
2557        */
2558
2559        int nextIndex;
2560        if (hasActivity) {
2561            final int N = mLruProcesses.size();
2562            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2563                // Process doesn't have activities, but has clients with
2564                // activities...  move it up, but one below the top (the top
2565                // should always have a real activity).
2566                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2567                mLruProcesses.add(N-1, app);
2568                // To keep it from spamming the LRU list (by making a bunch of clients),
2569                // we will push down any other entries owned by the app.
2570                final int uid = app.info.uid;
2571                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2572                    ProcessRecord subProc = mLruProcesses.get(i);
2573                    if (subProc.info.uid == uid) {
2574                        // We want to push this one down the list.  If the process after
2575                        // it is for the same uid, however, don't do so, because we don't
2576                        // want them internally to be re-ordered.
2577                        if (mLruProcesses.get(i-1).info.uid != uid) {
2578                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2579                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2580                            ProcessRecord tmp = mLruProcesses.get(i);
2581                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2582                            mLruProcesses.set(i-1, tmp);
2583                            i--;
2584                        }
2585                    } else {
2586                        // A gap, we can stop here.
2587                        break;
2588                    }
2589                }
2590            } else {
2591                // Process has activities, put it at the very tipsy-top.
2592                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2593                mLruProcesses.add(app);
2594            }
2595            nextIndex = mLruProcessServiceStart;
2596        } else if (hasService) {
2597            // Process has services, put it at the top of the service list.
2598            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2599            mLruProcesses.add(mLruProcessActivityStart, app);
2600            nextIndex = mLruProcessServiceStart;
2601            mLruProcessActivityStart++;
2602        } else  {
2603            // Process not otherwise of interest, it goes to the top of the non-service area.
2604            int index = mLruProcessServiceStart;
2605            if (client != null) {
2606                // If there is a client, don't allow the process to be moved up higher
2607                // in the list than that client.
2608                int clientIndex = mLruProcesses.lastIndexOf(client);
2609                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2610                        + " when updating " + app);
2611                if (clientIndex <= lrui) {
2612                    // Don't allow the client index restriction to push it down farther in the
2613                    // list than it already is.
2614                    clientIndex = lrui;
2615                }
2616                if (clientIndex >= 0 && index > clientIndex) {
2617                    index = clientIndex;
2618                }
2619            }
2620            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2621            mLruProcesses.add(index, app);
2622            nextIndex = index-1;
2623            mLruProcessActivityStart++;
2624            mLruProcessServiceStart++;
2625        }
2626
2627        // If the app is currently using a content provider or service,
2628        // bump those processes as well.
2629        for (int j=app.connections.size()-1; j>=0; j--) {
2630            ConnectionRecord cr = app.connections.valueAt(j);
2631            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2632                    && cr.binding.service.app != null
2633                    && cr.binding.service.app.lruSeq != mLruSeq
2634                    && !cr.binding.service.app.persistent) {
2635                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2636                        "service connection", cr, app);
2637            }
2638        }
2639        for (int j=app.conProviders.size()-1; j>=0; j--) {
2640            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2641            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2642                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2643                        "provider reference", cpr, app);
2644            }
2645        }
2646    }
2647
2648    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2649        if (uid == Process.SYSTEM_UID) {
2650            // The system gets to run in any process.  If there are multiple
2651            // processes with the same uid, just pick the first (this
2652            // should never happen).
2653            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2654            if (procs == null) return null;
2655            final int N = procs.size();
2656            for (int i = 0; i < N; i++) {
2657                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2658            }
2659        }
2660        ProcessRecord proc = mProcessNames.get(processName, uid);
2661        if (false && proc != null && !keepIfLarge
2662                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2663                && proc.lastCachedPss >= 4000) {
2664            // Turn this condition on to cause killing to happen regularly, for testing.
2665            if (proc.baseProcessTracker != null) {
2666                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2667            }
2668            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2669        } else if (proc != null && !keepIfLarge
2670                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2671                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2672            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2673            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2674                if (proc.baseProcessTracker != null) {
2675                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2676                }
2677                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2678            }
2679        }
2680        return proc;
2681    }
2682
2683    void ensurePackageDexOpt(String packageName) {
2684        IPackageManager pm = AppGlobals.getPackageManager();
2685        try {
2686            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2687                mDidDexOpt = true;
2688            }
2689        } catch (RemoteException e) {
2690        }
2691    }
2692
2693    boolean isNextTransitionForward() {
2694        int transit = mWindowManager.getPendingAppTransition();
2695        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2696                || transit == AppTransition.TRANSIT_TASK_OPEN
2697                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2698    }
2699
2700    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2701            String processName, String abiOverride, int uid, Runnable crashHandler) {
2702        synchronized(this) {
2703            ApplicationInfo info = new ApplicationInfo();
2704            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2705            // For isolated processes, the former contains the parent's uid and the latter the
2706            // actual uid of the isolated process.
2707            // In the special case introduced by this method (which is, starting an isolated
2708            // process directly from the SystemServer without an actual parent app process) the
2709            // closest thing to a parent's uid is SYSTEM_UID.
2710            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2711            // the |isolated| logic in the ProcessRecord constructor.
2712            info.uid = Process.SYSTEM_UID;
2713            info.processName = processName;
2714            info.className = entryPoint;
2715            info.packageName = "android";
2716            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2717                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2718                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2719                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2720                    crashHandler);
2721            return proc != null ? proc.pid : 0;
2722        }
2723    }
2724
2725    final ProcessRecord startProcessLocked(String processName,
2726            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2727            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2728            boolean isolated, boolean keepIfLarge) {
2729        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2730                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2731                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2732                null /* crashHandler */);
2733    }
2734
2735    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2736            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2737            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2738            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2739        long startTime = SystemClock.elapsedRealtime();
2740        ProcessRecord app;
2741        if (!isolated) {
2742            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2743            checkTime(startTime, "startProcess: after getProcessRecord");
2744        } else {
2745            // If this is an isolated process, it can't re-use an existing process.
2746            app = null;
2747        }
2748        // We don't have to do anything more if:
2749        // (1) There is an existing application record; and
2750        // (2) The caller doesn't think it is dead, OR there is no thread
2751        //     object attached to it so we know it couldn't have crashed; and
2752        // (3) There is a pid assigned to it, so it is either starting or
2753        //     already running.
2754        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2755                + " app=" + app + " knownToBeDead=" + knownToBeDead
2756                + " thread=" + (app != null ? app.thread : null)
2757                + " pid=" + (app != null ? app.pid : -1));
2758        if (app != null && app.pid > 0) {
2759            if (!knownToBeDead || app.thread == null) {
2760                // We already have the app running, or are waiting for it to
2761                // come up (we have a pid but not yet its thread), so keep it.
2762                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2763                // If this is a new package in the process, add the package to the list
2764                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2765                checkTime(startTime, "startProcess: done, added package to proc");
2766                return app;
2767            }
2768
2769            // An application record is attached to a previous process,
2770            // clean it up now.
2771            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2772            checkTime(startTime, "startProcess: bad proc running, killing");
2773            Process.killProcessGroup(app.info.uid, app.pid);
2774            handleAppDiedLocked(app, true, true);
2775            checkTime(startTime, "startProcess: done killing old proc");
2776        }
2777
2778        String hostingNameStr = hostingName != null
2779                ? hostingName.flattenToShortString() : null;
2780
2781        if (!isolated) {
2782            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2783                // If we are in the background, then check to see if this process
2784                // is bad.  If so, we will just silently fail.
2785                if (mBadProcesses.get(info.processName, info.uid) != null) {
2786                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2787                            + "/" + info.processName);
2788                    return null;
2789                }
2790            } else {
2791                // When the user is explicitly starting a process, then clear its
2792                // crash count so that we won't make it bad until they see at
2793                // least one crash dialog again, and make the process good again
2794                // if it had been bad.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2796                        + "/" + info.processName);
2797                mProcessCrashTimes.remove(info.processName, info.uid);
2798                if (mBadProcesses.get(info.processName, info.uid) != null) {
2799                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2800                            UserHandle.getUserId(info.uid), info.uid,
2801                            info.processName);
2802                    mBadProcesses.remove(info.processName, info.uid);
2803                    if (app != null) {
2804                        app.bad = false;
2805                    }
2806                }
2807            }
2808        }
2809
2810        if (app == null) {
2811            checkTime(startTime, "startProcess: creating new process record");
2812            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2813            if (app == null) {
2814                Slog.w(TAG, "Failed making new process record for "
2815                        + processName + "/" + info.uid + " isolated=" + isolated);
2816                return null;
2817            }
2818            app.crashHandler = crashHandler;
2819            mProcessNames.put(processName, app.uid, app);
2820            if (isolated) {
2821                mIsolatedProcesses.put(app.uid, app);
2822            }
2823            checkTime(startTime, "startProcess: done creating new process record");
2824        } else {
2825            // If this is a new package in the process, add the package to the list
2826            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2827            checkTime(startTime, "startProcess: added package to existing proc");
2828        }
2829
2830        // If the system is not ready yet, then hold off on starting this
2831        // process until it is.
2832        if (!mProcessesReady
2833                && !isAllowedWhileBooting(info)
2834                && !allowWhileBooting) {
2835            if (!mProcessesOnHold.contains(app)) {
2836                mProcessesOnHold.add(app);
2837            }
2838            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2839            checkTime(startTime, "startProcess: returning with proc on hold");
2840            return app;
2841        }
2842
2843        checkTime(startTime, "startProcess: stepping in to startProcess");
2844        startProcessLocked(
2845                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2846        checkTime(startTime, "startProcess: done starting proc!");
2847        return (app.pid != 0) ? app : null;
2848    }
2849
2850    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2851        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2852    }
2853
2854    private final void startProcessLocked(ProcessRecord app,
2855            String hostingType, String hostingNameStr) {
2856        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2857                null /* entryPoint */, null /* entryPointArgs */);
2858    }
2859
2860    private final void startProcessLocked(ProcessRecord app, String hostingType,
2861            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2862        long startTime = SystemClock.elapsedRealtime();
2863        if (app.pid > 0 && app.pid != MY_PID) {
2864            checkTime(startTime, "startProcess: removing from pids map");
2865            synchronized (mPidsSelfLocked) {
2866                mPidsSelfLocked.remove(app.pid);
2867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2868            }
2869            checkTime(startTime, "startProcess: done removing from pids map");
2870            app.setPid(0);
2871        }
2872
2873        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2874                "startProcessLocked removing on hold: " + app);
2875        mProcessesOnHold.remove(app);
2876
2877        checkTime(startTime, "startProcess: starting to update cpu stats");
2878        updateCpuStats();
2879        checkTime(startTime, "startProcess: done updating cpu stats");
2880
2881        try {
2882            int uid = app.uid;
2883
2884            int[] gids = null;
2885            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2886            if (!app.isolated) {
2887                int[] permGids = null;
2888                try {
2889                    checkTime(startTime, "startProcess: getting gids from package manager");
2890                    final PackageManager pm = mContext.getPackageManager();
2891                    permGids = pm.getPackageGids(app.info.packageName);
2892
2893                    if (Environment.isExternalStorageEmulated()) {
2894                        checkTime(startTime, "startProcess: checking external storage perm");
2895                        if (pm.checkPermission(
2896                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2897                                app.info.packageName) == PERMISSION_GRANTED) {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2899                        } else {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2901                        }
2902                    }
2903                } catch (PackageManager.NameNotFoundException e) {
2904                    Slog.w(TAG, "Unable to retrieve gids", e);
2905                }
2906
2907                /*
2908                 * Add shared application and profile GIDs so applications can share some
2909                 * resources like shared libraries and access user-wide resources
2910                 */
2911                if (permGids == null) {
2912                    gids = new int[2];
2913                } else {
2914                    gids = new int[permGids.length + 2];
2915                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2916                }
2917                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2918                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2919            }
2920            checkTime(startTime, "startProcess: building args");
2921            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2922                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2923                        && mTopComponent != null
2924                        && app.processName.equals(mTopComponent.getPackageName())) {
2925                    uid = 0;
2926                }
2927                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2928                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2929                    uid = 0;
2930                }
2931            }
2932            int debugFlags = 0;
2933            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2934                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2935                // Also turn on CheckJNI for debuggable apps. It's quite
2936                // awkward to turn on otherwise.
2937                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2938            }
2939            // Run the app in safe mode if its manifest requests so or the
2940            // system is booted in safe mode.
2941            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2942                mSafeMode == true) {
2943                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2944            }
2945            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2946                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2947            }
2948            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2949                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2950            }
2951            if ("1".equals(SystemProperties.get("debug.assert"))) {
2952                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2953            }
2954
2955            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2956            if (requiredAbi == null) {
2957                requiredAbi = Build.SUPPORTED_ABIS[0];
2958            }
2959
2960            String instructionSet = null;
2961            if (app.info.primaryCpuAbi != null) {
2962                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2963            }
2964
2965            // Start the process.  It will either succeed and return a result containing
2966            // the PID of the new process, or else throw a RuntimeException.
2967            boolean isActivityProcess = (entryPoint == null);
2968            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2969            checkTime(startTime, "startProcess: asking zygote to start proc");
2970            Process.ProcessStartResult startResult = Process.start(entryPoint,
2971                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2972                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2973                    app.info.dataDir, entryPointArgs);
2974            checkTime(startTime, "startProcess: returned from zygote!");
2975
2976            if (app.isolated) {
2977                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2978            }
2979            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2980            checkTime(startTime, "startProcess: done updating battery stats");
2981
2982            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2983                    UserHandle.getUserId(uid), startResult.pid, uid,
2984                    app.processName, hostingType,
2985                    hostingNameStr != null ? hostingNameStr : "");
2986
2987            if (app.persistent) {
2988                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2989            }
2990
2991            checkTime(startTime, "startProcess: building log message");
2992            StringBuilder buf = mStringBuilder;
2993            buf.setLength(0);
2994            buf.append("Start proc ");
2995            buf.append(app.processName);
2996            if (!isActivityProcess) {
2997                buf.append(" [");
2998                buf.append(entryPoint);
2999                buf.append("]");
3000            }
3001            buf.append(" for ");
3002            buf.append(hostingType);
3003            if (hostingNameStr != null) {
3004                buf.append(" ");
3005                buf.append(hostingNameStr);
3006            }
3007            buf.append(": pid=");
3008            buf.append(startResult.pid);
3009            buf.append(" uid=");
3010            buf.append(uid);
3011            buf.append(" gids={");
3012            if (gids != null) {
3013                for (int gi=0; gi<gids.length; gi++) {
3014                    if (gi != 0) buf.append(", ");
3015                    buf.append(gids[gi]);
3016
3017                }
3018            }
3019            buf.append("}");
3020            if (requiredAbi != null) {
3021                buf.append(" abi=");
3022                buf.append(requiredAbi);
3023            }
3024            Slog.i(TAG, buf.toString());
3025            app.setPid(startResult.pid);
3026            app.usingWrapper = startResult.usingWrapper;
3027            app.removed = false;
3028            app.killed = false;
3029            app.killedByAm = false;
3030            checkTime(startTime, "startProcess: starting to update pids map");
3031            synchronized (mPidsSelfLocked) {
3032                this.mPidsSelfLocked.put(startResult.pid, app);
3033                if (isActivityProcess) {
3034                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3035                    msg.obj = app;
3036                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3037                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3038                }
3039            }
3040            checkTime(startTime, "startProcess: done updating pids map");
3041        } catch (RuntimeException e) {
3042            // XXX do better error recovery.
3043            app.setPid(0);
3044            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3045            if (app.isolated) {
3046                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3047            }
3048            Slog.e(TAG, "Failure starting process " + app.processName, e);
3049        }
3050    }
3051
3052    void updateUsageStats(ActivityRecord component, boolean resumed) {
3053        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3054        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3055        if (resumed) {
3056            if (mUsageStatsService != null) {
3057                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3058                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3059            }
3060            synchronized (stats) {
3061                stats.noteActivityResumedLocked(component.app.uid);
3062            }
3063        } else {
3064            if (mUsageStatsService != null) {
3065                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3066                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3067            }
3068            synchronized (stats) {
3069                stats.noteActivityPausedLocked(component.app.uid);
3070            }
3071        }
3072    }
3073
3074    Intent getHomeIntent() {
3075        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3076        intent.setComponent(mTopComponent);
3077        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3078            intent.addCategory(Intent.CATEGORY_HOME);
3079        }
3080        return intent;
3081    }
3082
3083    boolean startHomeActivityLocked(int userId) {
3084        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3085                && mTopAction == null) {
3086            // We are running in factory test mode, but unable to find
3087            // the factory test app, so just sit around displaying the
3088            // error message and don't try to start anything.
3089            return false;
3090        }
3091        Intent intent = getHomeIntent();
3092        ActivityInfo aInfo =
3093            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3094        if (aInfo != null) {
3095            intent.setComponent(new ComponentName(
3096                    aInfo.applicationInfo.packageName, aInfo.name));
3097            // Don't do this if the home app is currently being
3098            // instrumented.
3099            aInfo = new ActivityInfo(aInfo);
3100            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3101            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3102                    aInfo.applicationInfo.uid, true);
3103            if (app == null || app.instrumentationClass == null) {
3104                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3105                mStackSupervisor.startHomeActivity(intent, aInfo);
3106            }
3107        }
3108
3109        return true;
3110    }
3111
3112    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3113        ActivityInfo ai = null;
3114        ComponentName comp = intent.getComponent();
3115        try {
3116            if (comp != null) {
3117                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3118            } else {
3119                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3120                        intent,
3121                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3122                            flags, userId);
3123
3124                if (info != null) {
3125                    ai = info.activityInfo;
3126                }
3127            }
3128        } catch (RemoteException e) {
3129            // ignore
3130        }
3131
3132        return ai;
3133    }
3134
3135    /**
3136     * Starts the "new version setup screen" if appropriate.
3137     */
3138    void startSetupActivityLocked() {
3139        // Only do this once per boot.
3140        if (mCheckedForSetup) {
3141            return;
3142        }
3143
3144        // We will show this screen if the current one is a different
3145        // version than the last one shown, and we are not running in
3146        // low-level factory test mode.
3147        final ContentResolver resolver = mContext.getContentResolver();
3148        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3149                Settings.Global.getInt(resolver,
3150                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3151            mCheckedForSetup = true;
3152
3153            // See if we should be showing the platform update setup UI.
3154            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3155            List<ResolveInfo> ris = mContext.getPackageManager()
3156                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3157
3158            // We don't allow third party apps to replace this.
3159            ResolveInfo ri = null;
3160            for (int i=0; ris != null && i<ris.size(); i++) {
3161                if ((ris.get(i).activityInfo.applicationInfo.flags
3162                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3163                    ri = ris.get(i);
3164                    break;
3165                }
3166            }
3167
3168            if (ri != null) {
3169                String vers = ri.activityInfo.metaData != null
3170                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3171                        : null;
3172                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3173                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3174                            Intent.METADATA_SETUP_VERSION);
3175                }
3176                String lastVers = Settings.Secure.getString(
3177                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3178                if (vers != null && !vers.equals(lastVers)) {
3179                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3180                    intent.setComponent(new ComponentName(
3181                            ri.activityInfo.packageName, ri.activityInfo.name));
3182                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3183                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3184                            null);
3185                }
3186            }
3187        }
3188    }
3189
3190    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3191        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3192    }
3193
3194    void enforceNotIsolatedCaller(String caller) {
3195        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3196            throw new SecurityException("Isolated process not allowed to call " + caller);
3197        }
3198    }
3199
3200    void enforceShellRestriction(String restriction, int userHandle) {
3201        if (Binder.getCallingUid() == Process.SHELL_UID) {
3202            if (userHandle < 0
3203                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3204                throw new SecurityException("Shell does not have permission to access user "
3205                        + userHandle);
3206            }
3207        }
3208    }
3209
3210    @Override
3211    public int getFrontActivityScreenCompatMode() {
3212        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3213        synchronized (this) {
3214            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3215        }
3216    }
3217
3218    @Override
3219    public void setFrontActivityScreenCompatMode(int mode) {
3220        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3221                "setFrontActivityScreenCompatMode");
3222        synchronized (this) {
3223            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3224        }
3225    }
3226
3227    @Override
3228    public int getPackageScreenCompatMode(String packageName) {
3229        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3230        synchronized (this) {
3231            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3232        }
3233    }
3234
3235    @Override
3236    public void setPackageScreenCompatMode(String packageName, int mode) {
3237        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3238                "setPackageScreenCompatMode");
3239        synchronized (this) {
3240            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3241        }
3242    }
3243
3244    @Override
3245    public boolean getPackageAskScreenCompat(String packageName) {
3246        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3247        synchronized (this) {
3248            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3249        }
3250    }
3251
3252    @Override
3253    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setPackageAskScreenCompat");
3256        synchronized (this) {
3257            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3258        }
3259    }
3260
3261    private void dispatchProcessesChanged() {
3262        int N;
3263        synchronized (this) {
3264            N = mPendingProcessChanges.size();
3265            if (mActiveProcessChanges.length < N) {
3266                mActiveProcessChanges = new ProcessChangeItem[N];
3267            }
3268            mPendingProcessChanges.toArray(mActiveProcessChanges);
3269            mAvailProcessChanges.addAll(mPendingProcessChanges);
3270            mPendingProcessChanges.clear();
3271            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3272        }
3273
3274        int i = mProcessObservers.beginBroadcast();
3275        while (i > 0) {
3276            i--;
3277            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3278            if (observer != null) {
3279                try {
3280                    for (int j=0; j<N; j++) {
3281                        ProcessChangeItem item = mActiveProcessChanges[j];
3282                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3284                                    + item.pid + " uid=" + item.uid + ": "
3285                                    + item.foregroundActivities);
3286                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3287                                    item.foregroundActivities);
3288                        }
3289                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3291                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3292                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3293                        }
3294                    }
3295                } catch (RemoteException e) {
3296                }
3297            }
3298        }
3299        mProcessObservers.finishBroadcast();
3300    }
3301
3302    private void dispatchProcessDied(int pid, int uid) {
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                    observer.onProcessDied(pid, uid);
3310                } catch (RemoteException e) {
3311                }
3312            }
3313        }
3314        mProcessObservers.finishBroadcast();
3315    }
3316
3317    @Override
3318    public final int startActivity(IApplicationThread caller, String callingPackage,
3319            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3320            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3321        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3322            resultWho, requestCode, startFlags, profilerInfo, options,
3323            UserHandle.getCallingUserId());
3324    }
3325
3326    @Override
3327    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3329            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3330        enforceNotIsolatedCaller("startActivity");
3331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3332                false, ALLOW_FULL_ONLY, "startActivity", null);
3333        // TODO: Switch to user app stacks here.
3334        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3336                profilerInfo, null, null, options, userId, null, null);
3337    }
3338
3339    @Override
3340    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3342            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3343
3344        // This is very dangerous -- it allows you to perform a start activity (including
3345        // permission grants) as any app that may launch one of your own activities.  So
3346        // we will only allow this to be done from activities that are part of the core framework,
3347        // and then only when they are running as the system.
3348        final ActivityRecord sourceRecord;
3349        final int targetUid;
3350        final String targetPackage;
3351        synchronized (this) {
3352            if (resultTo == null) {
3353                throw new SecurityException("Must be called from an activity");
3354            }
3355            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3356            if (sourceRecord == null) {
3357                throw new SecurityException("Called with bad activity token: " + resultTo);
3358            }
3359            if (!sourceRecord.info.packageName.equals("android")) {
3360                throw new SecurityException(
3361                        "Must be called from an activity that is declared in the android package");
3362            }
3363            if (sourceRecord.app == null) {
3364                throw new SecurityException("Called without a process attached to activity");
3365            }
3366            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3367                // This is still okay, as long as this activity is running under the
3368                // uid of the original calling activity.
3369                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3370                    throw new SecurityException(
3371                            "Calling activity in uid " + sourceRecord.app.uid
3372                                    + " must be system uid or original calling uid "
3373                                    + sourceRecord.launchedFromUid);
3374                }
3375            }
3376            targetUid = sourceRecord.launchedFromUid;
3377            targetPackage = sourceRecord.launchedFromPackage;
3378        }
3379
3380        if (userId == UserHandle.USER_NULL) {
3381            userId = UserHandle.getUserId(sourceRecord.app.uid);
3382        }
3383
3384        // TODO: Switch to user app stacks here.
3385        try {
3386            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3387                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3388                    null, null, options, userId, null, null);
3389            return ret;
3390        } catch (SecurityException e) {
3391            // XXX need to figure out how to propagate to original app.
3392            // A SecurityException here is generally actually a fault of the original
3393            // calling activity (such as a fairly granting permissions), so propagate it
3394            // back to them.
3395            /*
3396            StringBuilder msg = new StringBuilder();
3397            msg.append("While launching");
3398            msg.append(intent.toString());
3399            msg.append(": ");
3400            msg.append(e.getMessage());
3401            */
3402            throw e;
3403        }
3404    }
3405
3406    @Override
3407    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3408            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3409            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3410        enforceNotIsolatedCaller("startActivityAndWait");
3411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3412                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3413        WaitResult res = new WaitResult();
3414        // TODO: Switch to user app stacks here.
3415        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3416                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3417                options, userId, null, null);
3418        return res;
3419    }
3420
3421    @Override
3422    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3423            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3424            int startFlags, Configuration config, Bundle options, int userId) {
3425        enforceNotIsolatedCaller("startActivityWithConfig");
3426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3427                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3428        // TODO: Switch to user app stacks here.
3429        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3430                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3431                null, null, config, options, userId, null, null);
3432        return ret;
3433    }
3434
3435    @Override
3436    public int startActivityIntentSender(IApplicationThread caller,
3437            IntentSender intent, Intent fillInIntent, String resolvedType,
3438            IBinder resultTo, String resultWho, int requestCode,
3439            int flagsMask, int flagsValues, Bundle options) {
3440        enforceNotIsolatedCaller("startActivityIntentSender");
3441        // Refuse possible leaked file descriptors
3442        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        IIntentSender sender = intent.getTarget();
3447        if (!(sender instanceof PendingIntentRecord)) {
3448            throw new IllegalArgumentException("Bad PendingIntent object");
3449        }
3450
3451        PendingIntentRecord pir = (PendingIntentRecord)sender;
3452
3453        synchronized (this) {
3454            // If this is coming from the currently resumed activity, it is
3455            // effectively saying that app switches are allowed at this point.
3456            final ActivityStack stack = getFocusedStack();
3457            if (stack.mResumedActivity != null &&
3458                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3459                mAppSwitchesAllowedTime = 0;
3460            }
3461        }
3462        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3463                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3469            Intent intent, String resolvedType, IVoiceInteractionSession session,
3470            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3471            Bundle options, int userId) {
3472        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3473                != PackageManager.PERMISSION_GRANTED) {
3474            String msg = "Permission Denial: startVoiceActivity() from pid="
3475                    + Binder.getCallingPid()
3476                    + ", uid=" + Binder.getCallingUid()
3477                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3478            Slog.w(TAG, msg);
3479            throw new SecurityException(msg);
3480        }
3481        if (session == null || interactor == null) {
3482            throw new NullPointerException("null session or interactor");
3483        }
3484        userId = handleIncomingUser(callingPid, callingUid, userId,
3485                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3486        // TODO: Switch to user app stacks here.
3487        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3488                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3489                null, options, userId, null, null);
3490    }
3491
3492    @Override
3493    public boolean startNextMatchingActivity(IBinder callingActivity,
3494            Intent intent, Bundle options) {
3495        // Refuse possible leaked file descriptors
3496        if (intent != null && intent.hasFileDescriptors() == true) {
3497            throw new IllegalArgumentException("File descriptors passed in Intent");
3498        }
3499
3500        synchronized (this) {
3501            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3502            if (r == null) {
3503                ActivityOptions.abort(options);
3504                return false;
3505            }
3506            if (r.app == null || r.app.thread == null) {
3507                // The caller is not running...  d'oh!
3508                ActivityOptions.abort(options);
3509                return false;
3510            }
3511            intent = new Intent(intent);
3512            // The caller is not allowed to change the data.
3513            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3514            // And we are resetting to find the next component...
3515            intent.setComponent(null);
3516
3517            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3518
3519            ActivityInfo aInfo = null;
3520            try {
3521                List<ResolveInfo> resolves =
3522                    AppGlobals.getPackageManager().queryIntentActivities(
3523                            intent, r.resolvedType,
3524                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3525                            UserHandle.getCallingUserId());
3526
3527                // Look for the original activity in the list...
3528                final int N = resolves != null ? resolves.size() : 0;
3529                for (int i=0; i<N; i++) {
3530                    ResolveInfo rInfo = resolves.get(i);
3531                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3532                            && rInfo.activityInfo.name.equals(r.info.name)) {
3533                        // We found the current one...  the next matching is
3534                        // after it.
3535                        i++;
3536                        if (i<N) {
3537                            aInfo = resolves.get(i).activityInfo;
3538                        }
3539                        if (debug) {
3540                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3541                                    + "/" + r.info.name);
3542                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3543                                    + "/" + aInfo.name);
3544                        }
3545                        break;
3546                    }
3547                }
3548            } catch (RemoteException e) {
3549            }
3550
3551            if (aInfo == null) {
3552                // Nobody who is next!
3553                ActivityOptions.abort(options);
3554                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3555                return false;
3556            }
3557
3558            intent.setComponent(new ComponentName(
3559                    aInfo.applicationInfo.packageName, aInfo.name));
3560            intent.setFlags(intent.getFlags()&~(
3561                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3562                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3563                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3564                    Intent.FLAG_ACTIVITY_NEW_TASK));
3565
3566            // Okay now we need to start the new activity, replacing the
3567            // currently running activity.  This is a little tricky because
3568            // we want to start the new one as if the current one is finished,
3569            // but not finish the current one first so that there is no flicker.
3570            // And thus...
3571            final boolean wasFinishing = r.finishing;
3572            r.finishing = true;
3573
3574            // Propagate reply information over to the new activity.
3575            final ActivityRecord resultTo = r.resultTo;
3576            final String resultWho = r.resultWho;
3577            final int requestCode = r.requestCode;
3578            r.resultTo = null;
3579            if (resultTo != null) {
3580                resultTo.removeResultsLocked(r, resultWho, requestCode);
3581            }
3582
3583            final long origId = Binder.clearCallingIdentity();
3584            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3585                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3586                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3587                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3588            Binder.restoreCallingIdentity(origId);
3589
3590            r.finishing = wasFinishing;
3591            if (res != ActivityManager.START_SUCCESS) {
3592                return false;
3593            }
3594            return true;
3595        }
3596    }
3597
3598    @Override
3599    public final int startActivityFromRecents(int taskId, Bundle options) {
3600        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3601            String msg = "Permission Denial: startActivityFromRecents called without " +
3602                    START_TASKS_FROM_RECENTS;
3603            Slog.w(TAG, msg);
3604            throw new SecurityException(msg);
3605        }
3606        return startActivityFromRecentsInner(taskId, options);
3607    }
3608
3609    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3610        final TaskRecord task;
3611        final int callingUid;
3612        final String callingPackage;
3613        final Intent intent;
3614        final int userId;
3615        synchronized (this) {
3616            task = recentTaskForIdLocked(taskId);
3617            if (task == null) {
3618                throw new IllegalArgumentException("Task " + taskId + " not found.");
3619            }
3620            callingUid = task.mCallingUid;
3621            callingPackage = task.mCallingPackage;
3622            intent = task.intent;
3623            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3624            userId = task.userId;
3625        }
3626        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3627                options, userId, null, task);
3628    }
3629
3630    final int startActivityInPackage(int uid, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo,
3632            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3633            IActivityContainer container, TaskRecord inTask) {
3634
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3637
3638        // TODO: Switch to user app stacks here.
3639        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3641                null, null, null, options, userId, container, inTask);
3642        return ret;
3643    }
3644
3645    @Override
3646    public final int startActivities(IApplicationThread caller, String callingPackage,
3647            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3648            int userId) {
3649        enforceNotIsolatedCaller("startActivities");
3650        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3651                false, ALLOW_FULL_ONLY, "startActivity", null);
3652        // TODO: Switch to user app stacks here.
3653        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3654                resolvedTypes, resultTo, options, userId);
3655        return ret;
3656    }
3657
3658    final int startActivitiesInPackage(int uid, String callingPackage,
3659            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3660            Bundle options, int userId) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3666                resultTo, options, userId);
3667        return ret;
3668    }
3669
3670    //explicitly remove thd old information in mRecentTasks when removing existing user.
3671    private void removeRecentTasksForUserLocked(int userId) {
3672        if(userId <= 0) {
3673            Slog.i(TAG, "Can't remove recent task on user " + userId);
3674            return;
3675        }
3676
3677        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3678            TaskRecord tr = mRecentTasks.get(i);
3679            if (tr.userId == userId) {
3680                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3681                        + " when finishing user" + userId);
3682                mRecentTasks.remove(i);
3683                tr.removedFromRecents();
3684            }
3685        }
3686
3687        // Remove tasks from persistent storage.
3688        notifyTaskPersisterLocked(null, true);
3689    }
3690
3691    // Sort by taskId
3692    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3693        @Override
3694        public int compare(TaskRecord lhs, TaskRecord rhs) {
3695            return rhs.taskId - lhs.taskId;
3696        }
3697    };
3698
3699    // Extract the affiliates of the chain containing mRecentTasks[start].
3700    private int processNextAffiliateChainLocked(int start) {
3701        final TaskRecord startTask = mRecentTasks.get(start);
3702        final int affiliateId = startTask.mAffiliatedTaskId;
3703
3704        // Quick identification of isolated tasks. I.e. those not launched behind.
3705        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3706                startTask.mNextAffiliate == null) {
3707            // There is still a slim chance that there are other tasks that point to this task
3708            // and that the chain is so messed up that this task no longer points to them but
3709            // the gain of this optimization outweighs the risk.
3710            startTask.inRecents = true;
3711            return start + 1;
3712        }
3713
3714        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3715        mTmpRecents.clear();
3716        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3717            final TaskRecord task = mRecentTasks.get(i);
3718            if (task.mAffiliatedTaskId == affiliateId) {
3719                mRecentTasks.remove(i);
3720                mTmpRecents.add(task);
3721            }
3722        }
3723
3724        // Sort them all by taskId. That is the order they were create in and that order will
3725        // always be correct.
3726        Collections.sort(mTmpRecents, mTaskRecordComparator);
3727
3728        // Go through and fix up the linked list.
3729        // The first one is the end of the chain and has no next.
3730        final TaskRecord first = mTmpRecents.get(0);
3731        first.inRecents = true;
3732        if (first.mNextAffiliate != null) {
3733            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3734            first.setNextAffiliate(null);
3735            notifyTaskPersisterLocked(first, false);
3736        }
3737        // Everything in the middle is doubly linked from next to prev.
3738        final int tmpSize = mTmpRecents.size();
3739        for (int i = 0; i < tmpSize - 1; ++i) {
3740            final TaskRecord next = mTmpRecents.get(i);
3741            final TaskRecord prev = mTmpRecents.get(i + 1);
3742            if (next.mPrevAffiliate != prev) {
3743                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3744                        " setting prev=" + prev);
3745                next.setPrevAffiliate(prev);
3746                notifyTaskPersisterLocked(next, false);
3747            }
3748            if (prev.mNextAffiliate != next) {
3749                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3750                        " setting next=" + next);
3751                prev.setNextAffiliate(next);
3752                notifyTaskPersisterLocked(prev, false);
3753            }
3754            prev.inRecents = true;
3755        }
3756        // The last one is the beginning of the list and has no prev.
3757        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3758        if (last.mPrevAffiliate != null) {
3759            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3760            last.setPrevAffiliate(null);
3761            notifyTaskPersisterLocked(last, false);
3762        }
3763
3764        // Insert the group back into mRecentTasks at start.
3765        mRecentTasks.addAll(start, mTmpRecents);
3766
3767        // Let the caller know where we left off.
3768        return start + tmpSize;
3769    }
3770
3771    /**
3772     * Update the recent tasks lists: make sure tasks should still be here (their
3773     * applications / activities still exist), update their availability, fixup ordering
3774     * of affiliations.
3775     */
3776    void cleanupRecentTasksLocked(int userId) {
3777        if (mRecentTasks == null) {
3778            // Happens when called from the packagemanager broadcast before boot.
3779            return;
3780        }
3781
3782        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3783        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3784        final IPackageManager pm = AppGlobals.getPackageManager();
3785        final ActivityInfo dummyAct = new ActivityInfo();
3786        final ApplicationInfo dummyApp = new ApplicationInfo();
3787
3788        int N = mRecentTasks.size();
3789
3790        int[] users = userId == UserHandle.USER_ALL
3791                ? getUsersLocked() : new int[] { userId };
3792        for (int user : users) {
3793            for (int i = 0; i < N; i++) {
3794                TaskRecord task = mRecentTasks.get(i);
3795                if (task.userId != user) {
3796                    // Only look at tasks for the user ID of interest.
3797                    continue;
3798                }
3799                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3800                    // This situation is broken, and we should just get rid of it now.
3801                    mRecentTasks.remove(i);
3802                    task.removedFromRecents();
3803                    i--;
3804                    N--;
3805                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3806                    continue;
3807                }
3808                // Check whether this activity is currently available.
3809                if (task.realActivity != null) {
3810                    ActivityInfo ai = availActCache.get(task.realActivity);
3811                    if (ai == null) {
3812                        try {
3813                            ai = pm.getActivityInfo(task.realActivity,
3814                                    PackageManager.GET_UNINSTALLED_PACKAGES
3815                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3816                        } catch (RemoteException e) {
3817                            // Will never happen.
3818                            continue;
3819                        }
3820                        if (ai == null) {
3821                            ai = dummyAct;
3822                        }
3823                        availActCache.put(task.realActivity, ai);
3824                    }
3825                    if (ai == dummyAct) {
3826                        // This could be either because the activity no longer exists, or the
3827                        // app is temporarily gone.  For the former we want to remove the recents
3828                        // entry; for the latter we want to mark it as unavailable.
3829                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3830                        if (app == null) {
3831                            try {
3832                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3833                                        PackageManager.GET_UNINSTALLED_PACKAGES
3834                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3835                            } catch (RemoteException e) {
3836                                // Will never happen.
3837                                continue;
3838                            }
3839                            if (app == null) {
3840                                app = dummyApp;
3841                            }
3842                            availAppCache.put(task.realActivity.getPackageName(), app);
3843                        }
3844                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3845                            // Doesn't exist any more!  Good-bye.
3846                            mRecentTasks.remove(i);
3847                            task.removedFromRecents();
3848                            i--;
3849                            N--;
3850                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3851                            continue;
3852                        } else {
3853                            // Otherwise just not available for now.
3854                            if (task.isAvailable) {
3855                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3856                                        + task);
3857                            }
3858                            task.isAvailable = false;
3859                        }
3860                    } else {
3861                        if (!ai.enabled || !ai.applicationInfo.enabled
3862                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3863                            if (task.isAvailable) {
3864                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3865                                        + task + " (enabled=" + ai.enabled + "/"
3866                                        + ai.applicationInfo.enabled +  " flags="
3867                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3868                            }
3869                            task.isAvailable = false;
3870                        } else {
3871                            if (!task.isAvailable) {
3872                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3873                                        + task);
3874                            }
3875                            task.isAvailable = true;
3876                        }
3877                    }
3878                }
3879            }
3880        }
3881
3882        // Verify the affiliate chain for each task.
3883        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3884        }
3885
3886        mTmpRecents.clear();
3887        // mRecentTasks is now in sorted, affiliated order.
3888    }
3889
3890    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3891        int N = mRecentTasks.size();
3892        TaskRecord top = task;
3893        int topIndex = taskIndex;
3894        while (top.mNextAffiliate != null && topIndex > 0) {
3895            top = top.mNextAffiliate;
3896            topIndex--;
3897        }
3898        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3899                + topIndex + " from intial " + taskIndex);
3900        // Find the end of the chain, doing a sanity check along the way.
3901        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3902        int endIndex = topIndex;
3903        TaskRecord prev = top;
3904        while (endIndex < N) {
3905            TaskRecord cur = mRecentTasks.get(endIndex);
3906            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3907                    + endIndex + " " + cur);
3908            if (cur == top) {
3909                // Verify start of the chain.
3910                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3911                    Slog.wtf(TAG, "Bad chain @" + endIndex
3912                            + ": first task has next affiliate: " + prev);
3913                    sane = false;
3914                    break;
3915                }
3916            } else {
3917                // Verify middle of the chain's next points back to the one before.
3918                if (cur.mNextAffiliate != prev
3919                        || cur.mNextAffiliateTaskId != prev.taskId) {
3920                    Slog.wtf(TAG, "Bad chain @" + endIndex
3921                            + ": middle task " + cur + " @" + endIndex
3922                            + " has bad next affiliate "
3923                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3924                            + ", expected " + prev);
3925                    sane = false;
3926                    break;
3927                }
3928            }
3929            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3930                // Chain ends here.
3931                if (cur.mPrevAffiliate != null) {
3932                    Slog.wtf(TAG, "Bad chain @" + endIndex
3933                            + ": last task " + cur + " has previous affiliate "
3934                            + cur.mPrevAffiliate);
3935                    sane = false;
3936                }
3937                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3938                break;
3939            } else {
3940                // Verify middle of the chain's prev points to a valid item.
3941                if (cur.mPrevAffiliate == null) {
3942                    Slog.wtf(TAG, "Bad chain @" + endIndex
3943                            + ": task " + cur + " has previous affiliate "
3944                            + cur.mPrevAffiliate + " but should be id "
3945                            + cur.mPrevAffiliate);
3946                    sane = false;
3947                    break;
3948                }
3949            }
3950            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3951                Slog.wtf(TAG, "Bad chain @" + endIndex
3952                        + ": task " + cur + " has affiliated id "
3953                        + cur.mAffiliatedTaskId + " but should be "
3954                        + task.mAffiliatedTaskId);
3955                sane = false;
3956                break;
3957            }
3958            prev = cur;
3959            endIndex++;
3960            if (endIndex >= N) {
3961                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3962                        + ": last task " + prev);
3963                sane = false;
3964                break;
3965            }
3966        }
3967        if (sane) {
3968            if (endIndex < taskIndex) {
3969                Slog.wtf(TAG, "Bad chain @" + endIndex
3970                        + ": did not extend to task " + task + " @" + taskIndex);
3971                sane = false;
3972            }
3973        }
3974        if (sane) {
3975            // All looks good, we can just move all of the affiliated tasks
3976            // to the top.
3977            for (int i=topIndex; i<=endIndex; i++) {
3978                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3979                        + " from " + i + " to " + (i-topIndex));
3980                TaskRecord cur = mRecentTasks.remove(i);
3981                mRecentTasks.add(i-topIndex, cur);
3982            }
3983            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3984                    + " to " + endIndex);
3985            return true;
3986        }
3987
3988        // Whoops, couldn't do it.
3989        return false;
3990    }
3991
3992    final void addRecentTaskLocked(TaskRecord task) {
3993        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3994                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3995                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3996
3997        int N = mRecentTasks.size();
3998        // Quick case: check if the top-most recent task is the same.
3999        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4000            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4001            return;
4002        }
4003        // Another quick case: check if this is part of a set of affiliated
4004        // tasks that are at the top.
4005        if (isAffiliated && N > 0 && task.inRecents
4006                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4007            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4008                    + " at top when adding " + task);
4009            return;
4010        }
4011        // Another quick case: never add voice sessions.
4012        if (task.voiceSession != null) {
4013            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4014            return;
4015        }
4016
4017        boolean needAffiliationFix = false;
4018
4019        // Slightly less quick case: the task is already in recents, so all we need
4020        // to do is move it.
4021        if (task.inRecents) {
4022            int taskIndex = mRecentTasks.indexOf(task);
4023            if (taskIndex >= 0) {
4024                if (!isAffiliated) {
4025                    // Simple case: this is not an affiliated task, so we just move it to the front.
4026                    mRecentTasks.remove(taskIndex);
4027                    mRecentTasks.add(0, task);
4028                    notifyTaskPersisterLocked(task, false);
4029                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4030                            + " from " + taskIndex);
4031                    return;
4032                } else {
4033                    // More complicated: need to keep all affiliated tasks together.
4034                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4035                        // All went well.
4036                        return;
4037                    }
4038
4039                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4040                    // everything and then go through our general path of adding a new task.
4041                    needAffiliationFix = true;
4042                }
4043            } else {
4044                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4045                needAffiliationFix = true;
4046            }
4047        }
4048
4049        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4050        trimRecentsForTaskLocked(task, true);
4051
4052        N = mRecentTasks.size();
4053        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4054            final TaskRecord tr = mRecentTasks.remove(N - 1);
4055            tr.removedFromRecents();
4056            N--;
4057        }
4058        task.inRecents = true;
4059        if (!isAffiliated || needAffiliationFix) {
4060            // If this is a simple non-affiliated task, or we had some failure trying to
4061            // handle it as part of an affilated task, then just place it at the top.
4062            mRecentTasks.add(0, task);
4063        } else if (isAffiliated) {
4064            // If this is a new affiliated task, then move all of the affiliated tasks
4065            // to the front and insert this new one.
4066            TaskRecord other = task.mNextAffiliate;
4067            if (other == null) {
4068                other = task.mPrevAffiliate;
4069            }
4070            if (other != null) {
4071                int otherIndex = mRecentTasks.indexOf(other);
4072                if (otherIndex >= 0) {
4073                    // Insert new task at appropriate location.
4074                    int taskIndex;
4075                    if (other == task.mNextAffiliate) {
4076                        // We found the index of our next affiliation, which is who is
4077                        // before us in the list, so add after that point.
4078                        taskIndex = otherIndex+1;
4079                    } else {
4080                        // We found the index of our previous affiliation, which is who is
4081                        // after us in the list, so add at their position.
4082                        taskIndex = otherIndex;
4083                    }
4084                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4085                            + taskIndex + ": " + task);
4086                    mRecentTasks.add(taskIndex, task);
4087
4088                    // Now move everything to the front.
4089                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4090                        // All went well.
4091                        return;
4092                    }
4093
4094                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4095                    // everything and then go through our general path of adding a new task.
4096                    needAffiliationFix = true;
4097                } else {
4098                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4099                            + other);
4100                    needAffiliationFix = true;
4101                }
4102            } else {
4103                if (DEBUG_RECENTS) Slog.d(TAG,
4104                        "addRecent: adding affiliated task without next/prev:" + task);
4105                needAffiliationFix = true;
4106            }
4107        }
4108        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4109
4110        if (needAffiliationFix) {
4111            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4112            cleanupRecentTasksLocked(task.userId);
4113        }
4114    }
4115
4116    /**
4117     * If needed, remove oldest existing entries in recents that are for the same kind
4118     * of task as the given one.
4119     */
4120    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4121        int N = mRecentTasks.size();
4122        final Intent intent = task.intent;
4123        final boolean document = intent != null && intent.isDocument();
4124
4125        int maxRecents = task.maxRecents - 1;
4126        for (int i=0; i<N; i++) {
4127            final TaskRecord tr = mRecentTasks.get(i);
4128            if (task != tr) {
4129                if (task.userId != tr.userId) {
4130                    continue;
4131                }
4132                if (i > MAX_RECENT_BITMAPS) {
4133                    tr.freeLastThumbnail();
4134                }
4135                final Intent trIntent = tr.intent;
4136                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4137                    (intent == null || !intent.filterEquals(trIntent))) {
4138                    continue;
4139                }
4140                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4141                if (document && trIsDocument) {
4142                    // These are the same document activity (not necessarily the same doc).
4143                    if (maxRecents > 0) {
4144                        --maxRecents;
4145                        continue;
4146                    }
4147                    // Hit the maximum number of documents for this task. Fall through
4148                    // and remove this document from recents.
4149                } else if (document || trIsDocument) {
4150                    // Only one of these is a document. Not the droid we're looking for.
4151                    continue;
4152                }
4153            }
4154
4155            if (!doTrim) {
4156                // If the caller is not actually asking for a trim, just tell them we reached
4157                // a point where the trim would happen.
4158                return i;
4159            }
4160
4161            // Either task and tr are the same or, their affinities match or their intents match
4162            // and neither of them is a document, or they are documents using the same activity
4163            // and their maxRecents has been reached.
4164            tr.disposeThumbnail();
4165            mRecentTasks.remove(i);
4166            if (task != tr) {
4167                tr.removedFromRecents();
4168            }
4169            i--;
4170            N--;
4171            if (task.intent == null) {
4172                // If the new recent task we are adding is not fully
4173                // specified, then replace it with the existing recent task.
4174                task = tr;
4175            }
4176            notifyTaskPersisterLocked(tr, false);
4177        }
4178
4179        return -1;
4180    }
4181
4182    @Override
4183    public void reportActivityFullyDrawn(IBinder token) {
4184        synchronized (this) {
4185            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4186            if (r == null) {
4187                return;
4188            }
4189            r.reportFullyDrawnLocked();
4190        }
4191    }
4192
4193    @Override
4194    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4195        synchronized (this) {
4196            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4197            if (r == null) {
4198                return;
4199            }
4200            final long origId = Binder.clearCallingIdentity();
4201            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4202            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4203                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4204            if (config != null) {
4205                r.frozenBeforeDestroy = true;
4206                if (!updateConfigurationLocked(config, r, false, false)) {
4207                    mStackSupervisor.resumeTopActivitiesLocked();
4208                }
4209            }
4210            Binder.restoreCallingIdentity(origId);
4211        }
4212    }
4213
4214    @Override
4215    public int getRequestedOrientation(IBinder token) {
4216        synchronized (this) {
4217            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218            if (r == null) {
4219                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4220            }
4221            return mWindowManager.getAppOrientation(r.appToken);
4222        }
4223    }
4224
4225    /**
4226     * This is the internal entry point for handling Activity.finish().
4227     *
4228     * @param token The Binder token referencing the Activity we want to finish.
4229     * @param resultCode Result code, if any, from this Activity.
4230     * @param resultData Result data (Intent), if any, from this Activity.
4231     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4232     *            the root Activity in the task.
4233     *
4234     * @return Returns true if the activity successfully finished, or false if it is still running.
4235     */
4236    @Override
4237    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4238            boolean finishTask) {
4239        // Refuse possible leaked file descriptors
4240        if (resultData != null && resultData.hasFileDescriptors() == true) {
4241            throw new IllegalArgumentException("File descriptors passed in Intent");
4242        }
4243
4244        synchronized(this) {
4245            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4246            if (r == null) {
4247                return true;
4248            }
4249            // Keep track of the root activity of the task before we finish it
4250            TaskRecord tr = r.task;
4251            ActivityRecord rootR = tr.getRootActivity();
4252            if (rootR == null) {
4253                Slog.w(TAG, "Finishing task with all activities already finished");
4254            }
4255            // Do not allow task to finish in Lock Task mode.
4256            if (tr == mStackSupervisor.mLockTaskModeTask) {
4257                if (rootR == r) {
4258                    Slog.i(TAG, "Not finishing task in lock task mode");
4259                    mStackSupervisor.showLockTaskToast();
4260                    return false;
4261                }
4262            }
4263            if (mController != null) {
4264                // Find the first activity that is not finishing.
4265                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4266                if (next != null) {
4267                    // ask watcher if this is allowed
4268                    boolean resumeOK = true;
4269                    try {
4270                        resumeOK = mController.activityResuming(next.packageName);
4271                    } catch (RemoteException e) {
4272                        mController = null;
4273                        Watchdog.getInstance().setActivityController(null);
4274                    }
4275
4276                    if (!resumeOK) {
4277                        Slog.i(TAG, "Not finishing activity because controller resumed");
4278                        return false;
4279                    }
4280                }
4281            }
4282            final long origId = Binder.clearCallingIdentity();
4283            try {
4284                boolean res;
4285                if (finishTask && r == rootR) {
4286                    // If requested, remove the task that is associated to this activity only if it
4287                    // was the root activity in the task. The result code and data is ignored
4288                    // because we don't support returning them across task boundaries.
4289                    res = removeTaskByIdLocked(tr.taskId, false);
4290                    if (!res) {
4291                        Slog.i(TAG, "Removing task failed to finish activity");
4292                    }
4293                } else {
4294                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4295                            resultData, "app-request", true);
4296                    if (!res) {
4297                        Slog.i(TAG, "Failed to finish by app-request");
4298                    }
4299                }
4300                return res;
4301            } finally {
4302                Binder.restoreCallingIdentity(origId);
4303            }
4304        }
4305    }
4306
4307    @Override
4308    public final void finishHeavyWeightApp() {
4309        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4310                != PackageManager.PERMISSION_GRANTED) {
4311            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4312                    + Binder.getCallingPid()
4313                    + ", uid=" + Binder.getCallingUid()
4314                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4315            Slog.w(TAG, msg);
4316            throw new SecurityException(msg);
4317        }
4318
4319        synchronized(this) {
4320            if (mHeavyWeightProcess == null) {
4321                return;
4322            }
4323
4324            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4325                    mHeavyWeightProcess.activities);
4326            for (int i=0; i<activities.size(); i++) {
4327                ActivityRecord r = activities.get(i);
4328                if (!r.finishing) {
4329                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330                            null, "finish-heavy", true);
4331                }
4332            }
4333
4334            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335                    mHeavyWeightProcess.userId, 0));
4336            mHeavyWeightProcess = null;
4337        }
4338    }
4339
4340    @Override
4341    public void crashApplication(int uid, int initialPid, String packageName,
4342            String message) {
4343        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: crashApplication() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352
4353        synchronized(this) {
4354            ProcessRecord proc = null;
4355
4356            // Figure out which process to kill.  We don't trust that initialPid
4357            // still has any relation to current pids, so must scan through the
4358            // list.
4359            synchronized (mPidsSelfLocked) {
4360                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4362                    if (p.uid != uid) {
4363                        continue;
4364                    }
4365                    if (p.pid == initialPid) {
4366                        proc = p;
4367                        break;
4368                    }
4369                    if (p.pkgList.containsKey(packageName)) {
4370                        proc = p;
4371                    }
4372                }
4373            }
4374
4375            if (proc == null) {
4376                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377                        + " initialPid=" + initialPid
4378                        + " packageName=" + packageName);
4379                return;
4380            }
4381
4382            if (proc.thread != null) {
4383                if (proc.pid == Process.myPid()) {
4384                    Log.w(TAG, "crashApplication: trying to crash self!");
4385                    return;
4386                }
4387                long ident = Binder.clearCallingIdentity();
4388                try {
4389                    proc.thread.scheduleCrash(message);
4390                } catch (RemoteException e) {
4391                }
4392                Binder.restoreCallingIdentity(ident);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public final void finishSubActivity(IBinder token, String resultWho,
4399            int requestCode) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r != null) {
4404                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4405            }
4406            Binder.restoreCallingIdentity(origId);
4407        }
4408    }
4409
4410    @Override
4411    public boolean finishActivityAffinity(IBinder token) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416
4417                ActivityRecord rootR = r.task.getRootActivity();
4418                // Do not allow task to finish in Lock Task mode.
4419                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4420                    if (rootR == r) {
4421                        mStackSupervisor.showLockTaskToast();
4422                        return false;
4423                    }
4424                }
4425                boolean res = false;
4426                if (r != null) {
4427                    res = r.task.stack.finishActivityAffinityLocked(r);
4428                }
4429                return res;
4430            } finally {
4431                Binder.restoreCallingIdentity(origId);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public void finishVoiceTask(IVoiceInteractionSession session) {
4438        synchronized(this) {
4439            final long origId = Binder.clearCallingIdentity();
4440            try {
4441                mStackSupervisor.finishVoiceTask(session);
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446
4447    }
4448
4449    @Override
4450    public boolean releaseActivityInstance(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455                if (r.task == null || r.task.stack == null) {
4456                    return false;
4457                }
4458                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4459            } finally {
4460                Binder.restoreCallingIdentity(origId);
4461            }
4462        }
4463    }
4464
4465    @Override
4466    public void releaseSomeActivities(IApplicationThread appInt) {
4467        synchronized(this) {
4468            final long origId = Binder.clearCallingIdentity();
4469            try {
4470                ProcessRecord app = getRecordForAppLocked(appInt);
4471                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4472            } finally {
4473                Binder.restoreCallingIdentity(origId);
4474            }
4475        }
4476    }
4477
4478    @Override
4479    public boolean willActivityBeVisible(IBinder token) {
4480        synchronized(this) {
4481            ActivityStack stack = ActivityRecord.getStackLocked(token);
4482            if (stack != null) {
4483                return stack.willActivityBeVisibleLocked(token);
4484            }
4485            return false;
4486        }
4487    }
4488
4489    @Override
4490    public void overridePendingTransition(IBinder token, String packageName,
4491            int enterAnim, int exitAnim) {
4492        synchronized(this) {
4493            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4494            if (self == null) {
4495                return;
4496            }
4497
4498            final long origId = Binder.clearCallingIdentity();
4499
4500            if (self.state == ActivityState.RESUMED
4501                    || self.state == ActivityState.PAUSING) {
4502                mWindowManager.overridePendingAppTransition(packageName,
4503                        enterAnim, exitAnim, null);
4504            }
4505
4506            Binder.restoreCallingIdentity(origId);
4507        }
4508    }
4509
4510    /**
4511     * Main function for removing an existing process from the activity manager
4512     * as a result of that process going away.  Clears out all connections
4513     * to the process.
4514     */
4515    private final void handleAppDiedLocked(ProcessRecord app,
4516            boolean restarting, boolean allowRestart) {
4517        int pid = app.pid;
4518        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4519        if (!kept && !restarting) {
4520            removeLruProcessLocked(app);
4521            if (pid > 0) {
4522                ProcessList.remove(pid);
4523            }
4524        }
4525
4526        if (mProfileProc == app) {
4527            clearProfilerLocked();
4528        }
4529
4530        // Remove this application's activities from active lists.
4531        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4532
4533        app.activities.clear();
4534
4535        if (app.instrumentationClass != null) {
4536            Slog.w(TAG, "Crash of app " + app.processName
4537                  + " running instrumentation " + app.instrumentationClass);
4538            Bundle info = new Bundle();
4539            info.putString("shortMsg", "Process crashed.");
4540            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4541        }
4542
4543        if (!restarting) {
4544            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4545                // If there was nothing to resume, and we are not already
4546                // restarting this process, but there is a visible activity that
4547                // is hosted by the process...  then make sure all visible
4548                // activities are running, taking care of restarting this
4549                // process.
4550                if (hasVisibleActivities) {
4551                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4552                }
4553            }
4554        }
4555    }
4556
4557    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4558        IBinder threadBinder = thread.asBinder();
4559        // Find the application record.
4560        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4561            ProcessRecord rec = mLruProcesses.get(i);
4562            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4563                return i;
4564            }
4565        }
4566        return -1;
4567    }
4568
4569    final ProcessRecord getRecordForAppLocked(
4570            IApplicationThread thread) {
4571        if (thread == null) {
4572            return null;
4573        }
4574
4575        int appIndex = getLRURecordIndexForAppLocked(thread);
4576        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4577    }
4578
4579    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4580        // If there are no longer any background processes running,
4581        // and the app that died was not running instrumentation,
4582        // then tell everyone we are now low on memory.
4583        boolean haveBg = false;
4584        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4585            ProcessRecord rec = mLruProcesses.get(i);
4586            if (rec.thread != null
4587                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4588                haveBg = true;
4589                break;
4590            }
4591        }
4592
4593        if (!haveBg) {
4594            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4595            if (doReport) {
4596                long now = SystemClock.uptimeMillis();
4597                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4598                    doReport = false;
4599                } else {
4600                    mLastMemUsageReportTime = now;
4601                }
4602            }
4603            final ArrayList<ProcessMemInfo> memInfos
4604                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4605            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4606            long now = SystemClock.uptimeMillis();
4607            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4608                ProcessRecord rec = mLruProcesses.get(i);
4609                if (rec == dyingProc || rec.thread == null) {
4610                    continue;
4611                }
4612                if (doReport) {
4613                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4614                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4615                }
4616                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4617                    // The low memory report is overriding any current
4618                    // state for a GC request.  Make sure to do
4619                    // heavy/important/visible/foreground processes first.
4620                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4621                        rec.lastRequestedGc = 0;
4622                    } else {
4623                        rec.lastRequestedGc = rec.lastLowMemory;
4624                    }
4625                    rec.reportLowMemory = true;
4626                    rec.lastLowMemory = now;
4627                    mProcessesToGc.remove(rec);
4628                    addProcessToGcListLocked(rec);
4629                }
4630            }
4631            if (doReport) {
4632                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4633                mHandler.sendMessage(msg);
4634            }
4635            scheduleAppGcsLocked();
4636        }
4637    }
4638
4639    final void appDiedLocked(ProcessRecord app) {
4640       appDiedLocked(app, app.pid, app.thread);
4641    }
4642
4643    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4644        // First check if this ProcessRecord is actually active for the pid.
4645        synchronized (mPidsSelfLocked) {
4646            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4647            if (curProc != app) {
4648                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4649                return;
4650            }
4651        }
4652
4653        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4654        synchronized (stats) {
4655            stats.noteProcessDiedLocked(app.info.uid, pid);
4656        }
4657
4658        Process.killProcessQuiet(pid);
4659        Process.killProcessGroup(app.info.uid, pid);
4660        app.killed = true;
4661
4662        // Clean up already done if the process has been re-started.
4663        if (app.pid == pid && app.thread != null &&
4664                app.thread.asBinder() == thread.asBinder()) {
4665            boolean doLowMem = app.instrumentationClass == null;
4666            boolean doOomAdj = doLowMem;
4667            if (!app.killedByAm) {
4668                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4669                        + ") has died");
4670                mAllowLowerMemLevel = true;
4671            } else {
4672                // Note that we always want to do oom adj to update our state with the
4673                // new number of procs.
4674                mAllowLowerMemLevel = false;
4675                doLowMem = false;
4676            }
4677            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4678            if (DEBUG_CLEANUP) Slog.v(
4679                TAG, "Dying app: " + app + ", pid: " + pid
4680                + ", thread: " + thread.asBinder());
4681            handleAppDiedLocked(app, false, true);
4682
4683            if (doOomAdj) {
4684                updateOomAdjLocked();
4685            }
4686            if (doLowMem) {
4687                doLowMemReportIfNeededLocked(app);
4688            }
4689        } else if (app.pid != pid) {
4690            // A new process has already been started.
4691            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4692                    + ") has died and restarted (pid " + app.pid + ").");
4693            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4694        } else if (DEBUG_PROCESSES) {
4695            Slog.d(TAG, "Received spurious death notification for thread "
4696                    + thread.asBinder());
4697        }
4698    }
4699
4700    /**
4701     * If a stack trace dump file is configured, dump process stack traces.
4702     * @param clearTraces causes the dump file to be erased prior to the new
4703     *    traces being written, if true; when false, the new traces will be
4704     *    appended to any existing file content.
4705     * @param firstPids of dalvik VM processes to dump stack traces for first
4706     * @param lastPids of dalvik VM processes to dump stack traces for last
4707     * @param nativeProcs optional list of native process names to dump stack crawls
4708     * @return file containing stack traces, or null if no dump file is configured
4709     */
4710    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4711            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4712        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4713        if (tracesPath == null || tracesPath.length() == 0) {
4714            return null;
4715        }
4716
4717        File tracesFile = new File(tracesPath);
4718        try {
4719            File tracesDir = tracesFile.getParentFile();
4720            if (!tracesDir.exists()) {
4721                tracesDir.mkdirs();
4722                if (!SELinux.restorecon(tracesDir)) {
4723                    return null;
4724                }
4725            }
4726            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4727
4728            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4729            tracesFile.createNewFile();
4730            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4731        } catch (IOException e) {
4732            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4733            return null;
4734        }
4735
4736        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4737        return tracesFile;
4738    }
4739
4740    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4741            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4742        // Use a FileObserver to detect when traces finish writing.
4743        // The order of traces is considered important to maintain for legibility.
4744        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4745            @Override
4746            public synchronized void onEvent(int event, String path) { notify(); }
4747        };
4748
4749        try {
4750            observer.startWatching();
4751
4752            // First collect all of the stacks of the most important pids.
4753            if (firstPids != null) {
4754                try {
4755                    int num = firstPids.size();
4756                    for (int i = 0; i < num; i++) {
4757                        synchronized (observer) {
4758                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4759                            observer.wait(200);  // Wait for write-close, give up after 200msec
4760                        }
4761                    }
4762                } catch (InterruptedException e) {
4763                    Slog.wtf(TAG, e);
4764                }
4765            }
4766
4767            // Next collect the stacks of the native pids
4768            if (nativeProcs != null) {
4769                int[] pids = Process.getPidsForCommands(nativeProcs);
4770                if (pids != null) {
4771                    for (int pid : pids) {
4772                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4773                    }
4774                }
4775            }
4776
4777            // Lastly, measure CPU usage.
4778            if (processCpuTracker != null) {
4779                processCpuTracker.init();
4780                System.gc();
4781                processCpuTracker.update();
4782                try {
4783                    synchronized (processCpuTracker) {
4784                        processCpuTracker.wait(500); // measure over 1/2 second.
4785                    }
4786                } catch (InterruptedException e) {
4787                }
4788                processCpuTracker.update();
4789
4790                // We'll take the stack crawls of just the top apps using CPU.
4791                final int N = processCpuTracker.countWorkingStats();
4792                int numProcs = 0;
4793                for (int i=0; i<N && numProcs<5; i++) {
4794                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4795                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4796                        numProcs++;
4797                        try {
4798                            synchronized (observer) {
4799                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4800                                observer.wait(200);  // Wait for write-close, give up after 200msec
4801                            }
4802                        } catch (InterruptedException e) {
4803                            Slog.wtf(TAG, e);
4804                        }
4805
4806                    }
4807                }
4808            }
4809        } finally {
4810            observer.stopWatching();
4811        }
4812    }
4813
4814    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4815        if (true || IS_USER_BUILD) {
4816            return;
4817        }
4818        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4819        if (tracesPath == null || tracesPath.length() == 0) {
4820            return;
4821        }
4822
4823        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4824        StrictMode.allowThreadDiskWrites();
4825        try {
4826            final File tracesFile = new File(tracesPath);
4827            final File tracesDir = tracesFile.getParentFile();
4828            final File tracesTmp = new File(tracesDir, "__tmp__");
4829            try {
4830                if (!tracesDir.exists()) {
4831                    tracesDir.mkdirs();
4832                    if (!SELinux.restorecon(tracesDir.getPath())) {
4833                        return;
4834                    }
4835                }
4836                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4837
4838                if (tracesFile.exists()) {
4839                    tracesTmp.delete();
4840                    tracesFile.renameTo(tracesTmp);
4841                }
4842                StringBuilder sb = new StringBuilder();
4843                Time tobj = new Time();
4844                tobj.set(System.currentTimeMillis());
4845                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4846                sb.append(": ");
4847                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4848                sb.append(" since ");
4849                sb.append(msg);
4850                FileOutputStream fos = new FileOutputStream(tracesFile);
4851                fos.write(sb.toString().getBytes());
4852                if (app == null) {
4853                    fos.write("\n*** No application process!".getBytes());
4854                }
4855                fos.close();
4856                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4857            } catch (IOException e) {
4858                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4859                return;
4860            }
4861
4862            if (app != null) {
4863                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4864                firstPids.add(app.pid);
4865                dumpStackTraces(tracesPath, firstPids, null, null, null);
4866            }
4867
4868            File lastTracesFile = null;
4869            File curTracesFile = null;
4870            for (int i=9; i>=0; i--) {
4871                String name = String.format(Locale.US, "slow%02d.txt", i);
4872                curTracesFile = new File(tracesDir, name);
4873                if (curTracesFile.exists()) {
4874                    if (lastTracesFile != null) {
4875                        curTracesFile.renameTo(lastTracesFile);
4876                    } else {
4877                        curTracesFile.delete();
4878                    }
4879                }
4880                lastTracesFile = curTracesFile;
4881            }
4882            tracesFile.renameTo(curTracesFile);
4883            if (tracesTmp.exists()) {
4884                tracesTmp.renameTo(tracesFile);
4885            }
4886        } finally {
4887            StrictMode.setThreadPolicy(oldPolicy);
4888        }
4889    }
4890
4891    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4892            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4893        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4894        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4895
4896        if (mController != null) {
4897            try {
4898                // 0 == continue, -1 = kill process immediately
4899                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4900                if (res < 0 && app.pid != MY_PID) {
4901                    app.kill("anr", true);
4902                }
4903            } catch (RemoteException e) {
4904                mController = null;
4905                Watchdog.getInstance().setActivityController(null);
4906            }
4907        }
4908
4909        long anrTime = SystemClock.uptimeMillis();
4910        if (MONITOR_CPU_USAGE) {
4911            updateCpuStatsNow();
4912        }
4913
4914        synchronized (this) {
4915            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4916            if (mShuttingDown) {
4917                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4918                return;
4919            } else if (app.notResponding) {
4920                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4921                return;
4922            } else if (app.crashing) {
4923                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4924                return;
4925            }
4926
4927            // In case we come through here for the same app before completing
4928            // this one, mark as anring now so we will bail out.
4929            app.notResponding = true;
4930
4931            // Log the ANR to the event log.
4932            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4933                    app.processName, app.info.flags, annotation);
4934
4935            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4936            firstPids.add(app.pid);
4937
4938            int parentPid = app.pid;
4939            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4940            if (parentPid != app.pid) firstPids.add(parentPid);
4941
4942            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4943
4944            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4945                ProcessRecord r = mLruProcesses.get(i);
4946                if (r != null && r.thread != null) {
4947                    int pid = r.pid;
4948                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4949                        if (r.persistent) {
4950                            firstPids.add(pid);
4951                        } else {
4952                            lastPids.put(pid, Boolean.TRUE);
4953                        }
4954                    }
4955                }
4956            }
4957        }
4958
4959        // Log the ANR to the main log.
4960        StringBuilder info = new StringBuilder();
4961        info.setLength(0);
4962        info.append("ANR in ").append(app.processName);
4963        if (activity != null && activity.shortComponentName != null) {
4964            info.append(" (").append(activity.shortComponentName).append(")");
4965        }
4966        info.append("\n");
4967        info.append("PID: ").append(app.pid).append("\n");
4968        if (annotation != null) {
4969            info.append("Reason: ").append(annotation).append("\n");
4970        }
4971        if (parent != null && parent != activity) {
4972            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4973        }
4974
4975        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4976
4977        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4978                NATIVE_STACKS_OF_INTEREST);
4979
4980        String cpuInfo = null;
4981        if (MONITOR_CPU_USAGE) {
4982            updateCpuStatsNow();
4983            synchronized (mProcessCpuTracker) {
4984                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4985            }
4986            info.append(processCpuTracker.printCurrentLoad());
4987            info.append(cpuInfo);
4988        }
4989
4990        info.append(processCpuTracker.printCurrentState(anrTime));
4991
4992        Slog.e(TAG, info.toString());
4993        if (tracesFile == null) {
4994            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4995            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4996        }
4997
4998        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4999                cpuInfo, tracesFile, null);
5000
5001        if (mController != null) {
5002            try {
5003                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5004                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5005                if (res != 0) {
5006                    if (res < 0 && app.pid != MY_PID) {
5007                        app.kill("anr", true);
5008                    } else {
5009                        synchronized (this) {
5010                            mServices.scheduleServiceTimeoutLocked(app);
5011                        }
5012                    }
5013                    return;
5014                }
5015            } catch (RemoteException e) {
5016                mController = null;
5017                Watchdog.getInstance().setActivityController(null);
5018            }
5019        }
5020
5021        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5022        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5023                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5024
5025        synchronized (this) {
5026            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5027
5028            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5029                app.kill("bg anr", true);
5030                return;
5031            }
5032
5033            // Set the app's notResponding state, and look up the errorReportReceiver
5034            makeAppNotRespondingLocked(app,
5035                    activity != null ? activity.shortComponentName : null,
5036                    annotation != null ? "ANR " + annotation : "ANR",
5037                    info.toString());
5038
5039            // Bring up the infamous App Not Responding dialog
5040            Message msg = Message.obtain();
5041            HashMap<String, Object> map = new HashMap<String, Object>();
5042            msg.what = SHOW_NOT_RESPONDING_MSG;
5043            msg.obj = map;
5044            msg.arg1 = aboveSystem ? 1 : 0;
5045            map.put("app", app);
5046            if (activity != null) {
5047                map.put("activity", activity);
5048            }
5049
5050            mHandler.sendMessage(msg);
5051        }
5052    }
5053
5054    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5055        if (!mLaunchWarningShown) {
5056            mLaunchWarningShown = true;
5057            mHandler.post(new Runnable() {
5058                @Override
5059                public void run() {
5060                    synchronized (ActivityManagerService.this) {
5061                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5062                        d.show();
5063                        mHandler.postDelayed(new Runnable() {
5064                            @Override
5065                            public void run() {
5066                                synchronized (ActivityManagerService.this) {
5067                                    d.dismiss();
5068                                    mLaunchWarningShown = false;
5069                                }
5070                            }
5071                        }, 4000);
5072                    }
5073                }
5074            });
5075        }
5076    }
5077
5078    @Override
5079    public boolean clearApplicationUserData(final String packageName,
5080            final IPackageDataObserver observer, int userId) {
5081        enforceNotIsolatedCaller("clearApplicationUserData");
5082        int uid = Binder.getCallingUid();
5083        int pid = Binder.getCallingPid();
5084        userId = handleIncomingUser(pid, uid,
5085                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5086        long callingId = Binder.clearCallingIdentity();
5087        try {
5088            IPackageManager pm = AppGlobals.getPackageManager();
5089            int pkgUid = -1;
5090            synchronized(this) {
5091                try {
5092                    pkgUid = pm.getPackageUid(packageName, userId);
5093                } catch (RemoteException e) {
5094                }
5095                if (pkgUid == -1) {
5096                    Slog.w(TAG, "Invalid packageName: " + packageName);
5097                    if (observer != null) {
5098                        try {
5099                            observer.onRemoveCompleted(packageName, false);
5100                        } catch (RemoteException e) {
5101                            Slog.i(TAG, "Observer no longer exists.");
5102                        }
5103                    }
5104                    return false;
5105                }
5106                if (uid == pkgUid || checkComponentPermission(
5107                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5108                        pid, uid, -1, true)
5109                        == PackageManager.PERMISSION_GRANTED) {
5110                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5111                } else {
5112                    throw new SecurityException("PID " + pid + " does not have permission "
5113                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5114                                    + " of package " + packageName);
5115                }
5116
5117                // Remove all tasks match the cleared application package and user
5118                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5119                    final TaskRecord tr = mRecentTasks.get(i);
5120                    final String taskPackageName =
5121                            tr.getBaseIntent().getComponent().getPackageName();
5122                    if (tr.userId != userId) continue;
5123                    if (!taskPackageName.equals(packageName)) continue;
5124                    removeTaskByIdLocked(tr.taskId, false);
5125                }
5126            }
5127
5128            try {
5129                // Clear application user data
5130                pm.clearApplicationUserData(packageName, observer, userId);
5131
5132                synchronized(this) {
5133                    // Remove all permissions granted from/to this package
5134                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5135                }
5136
5137                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5138                        Uri.fromParts("package", packageName, null));
5139                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5140                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5141                        null, null, 0, null, null, null, false, false, userId);
5142            } catch (RemoteException e) {
5143            }
5144        } finally {
5145            Binder.restoreCallingIdentity(callingId);
5146        }
5147        return true;
5148    }
5149
5150    @Override
5151    public void killBackgroundProcesses(final String packageName, int userId) {
5152        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5153                != PackageManager.PERMISSION_GRANTED &&
5154                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5155                        != PackageManager.PERMISSION_GRANTED) {
5156            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5157                    + Binder.getCallingPid()
5158                    + ", uid=" + Binder.getCallingUid()
5159                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5160            Slog.w(TAG, msg);
5161            throw new SecurityException(msg);
5162        }
5163
5164        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5165                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5166        long callingId = Binder.clearCallingIdentity();
5167        try {
5168            IPackageManager pm = AppGlobals.getPackageManager();
5169            synchronized(this) {
5170                int appId = -1;
5171                try {
5172                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5173                } catch (RemoteException e) {
5174                }
5175                if (appId == -1) {
5176                    Slog.w(TAG, "Invalid packageName: " + packageName);
5177                    return;
5178                }
5179                killPackageProcessesLocked(packageName, appId, userId,
5180                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5181            }
5182        } finally {
5183            Binder.restoreCallingIdentity(callingId);
5184        }
5185    }
5186
5187    @Override
5188    public void killAllBackgroundProcesses() {
5189        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5190                != PackageManager.PERMISSION_GRANTED) {
5191            String msg = "Permission Denial: killAllBackgroundProcesses() 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        long callingId = Binder.clearCallingIdentity();
5200        try {
5201            synchronized(this) {
5202                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5203                final int NP = mProcessNames.getMap().size();
5204                for (int ip=0; ip<NP; ip++) {
5205                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5206                    final int NA = apps.size();
5207                    for (int ia=0; ia<NA; ia++) {
5208                        ProcessRecord app = apps.valueAt(ia);
5209                        if (app.persistent) {
5210                            // we don't kill persistent processes
5211                            continue;
5212                        }
5213                        if (app.removed) {
5214                            procs.add(app);
5215                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5216                            app.removed = true;
5217                            procs.add(app);
5218                        }
5219                    }
5220                }
5221
5222                int N = procs.size();
5223                for (int i=0; i<N; i++) {
5224                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5225                }
5226                mAllowLowerMemLevel = true;
5227                updateOomAdjLocked();
5228                doLowMemReportIfNeededLocked(null);
5229            }
5230        } finally {
5231            Binder.restoreCallingIdentity(callingId);
5232        }
5233    }
5234
5235    @Override
5236    public void forceStopPackage(final String packageName, int userId) {
5237        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5238                != PackageManager.PERMISSION_GRANTED) {
5239            String msg = "Permission Denial: forceStopPackage() from pid="
5240                    + Binder.getCallingPid()
5241                    + ", uid=" + Binder.getCallingUid()
5242                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5243            Slog.w(TAG, msg);
5244            throw new SecurityException(msg);
5245        }
5246        final int callingPid = Binder.getCallingPid();
5247        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5248                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5249        long callingId = Binder.clearCallingIdentity();
5250        try {
5251            IPackageManager pm = AppGlobals.getPackageManager();
5252            synchronized(this) {
5253                int[] users = userId == UserHandle.USER_ALL
5254                        ? getUsersLocked() : new int[] { userId };
5255                for (int user : users) {
5256                    int pkgUid = -1;
5257                    try {
5258                        pkgUid = pm.getPackageUid(packageName, user);
5259                    } catch (RemoteException e) {
5260                    }
5261                    if (pkgUid == -1) {
5262                        Slog.w(TAG, "Invalid packageName: " + packageName);
5263                        continue;
5264                    }
5265                    try {
5266                        pm.setPackageStoppedState(packageName, true, user);
5267                    } catch (RemoteException e) {
5268                    } catch (IllegalArgumentException e) {
5269                        Slog.w(TAG, "Failed trying to unstop package "
5270                                + packageName + ": " + e);
5271                    }
5272                    if (isUserRunningLocked(user, false)) {
5273                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5274                    }
5275                }
5276            }
5277        } finally {
5278            Binder.restoreCallingIdentity(callingId);
5279        }
5280    }
5281
5282    @Override
5283    public void addPackageDependency(String packageName) {
5284        synchronized (this) {
5285            int callingPid = Binder.getCallingPid();
5286            if (callingPid == Process.myPid()) {
5287                //  Yeah, um, no.
5288                Slog.w(TAG, "Can't addPackageDependency on system process");
5289                return;
5290            }
5291            ProcessRecord proc;
5292            synchronized (mPidsSelfLocked) {
5293                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5294            }
5295            if (proc != null) {
5296                if (proc.pkgDeps == null) {
5297                    proc.pkgDeps = new ArraySet<String>(1);
5298                }
5299                proc.pkgDeps.add(packageName);
5300            }
5301        }
5302    }
5303
5304    /*
5305     * The pkg name and app id have to be specified.
5306     */
5307    @Override
5308    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5309        if (pkg == null) {
5310            return;
5311        }
5312        // Make sure the uid is valid.
5313        if (appid < 0) {
5314            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5315            return;
5316        }
5317        int callerUid = Binder.getCallingUid();
5318        // Only the system server can kill an application
5319        if (callerUid == Process.SYSTEM_UID) {
5320            // Post an aysnc message to kill the application
5321            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5322            msg.arg1 = appid;
5323            msg.arg2 = 0;
5324            Bundle bundle = new Bundle();
5325            bundle.putString("pkg", pkg);
5326            bundle.putString("reason", reason);
5327            msg.obj = bundle;
5328            mHandler.sendMessage(msg);
5329        } else {
5330            throw new SecurityException(callerUid + " cannot kill pkg: " +
5331                    pkg);
5332        }
5333    }
5334
5335    @Override
5336    public void closeSystemDialogs(String reason) {
5337        enforceNotIsolatedCaller("closeSystemDialogs");
5338
5339        final int pid = Binder.getCallingPid();
5340        final int uid = Binder.getCallingUid();
5341        final long origId = Binder.clearCallingIdentity();
5342        try {
5343            synchronized (this) {
5344                // Only allow this from foreground processes, so that background
5345                // applications can't abuse it to prevent system UI from being shown.
5346                if (uid >= Process.FIRST_APPLICATION_UID) {
5347                    ProcessRecord proc;
5348                    synchronized (mPidsSelfLocked) {
5349                        proc = mPidsSelfLocked.get(pid);
5350                    }
5351                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5352                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5353                                + " from background process " + proc);
5354                        return;
5355                    }
5356                }
5357                closeSystemDialogsLocked(reason);
5358            }
5359        } finally {
5360            Binder.restoreCallingIdentity(origId);
5361        }
5362    }
5363
5364    void closeSystemDialogsLocked(String reason) {
5365        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5366        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5367                | Intent.FLAG_RECEIVER_FOREGROUND);
5368        if (reason != null) {
5369            intent.putExtra("reason", reason);
5370        }
5371        mWindowManager.closeSystemDialogs(reason);
5372
5373        mStackSupervisor.closeSystemDialogsLocked();
5374
5375        broadcastIntentLocked(null, null, intent, null,
5376                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5377                Process.SYSTEM_UID, UserHandle.USER_ALL);
5378    }
5379
5380    @Override
5381    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5382        enforceNotIsolatedCaller("getProcessMemoryInfo");
5383        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5384        for (int i=pids.length-1; i>=0; i--) {
5385            ProcessRecord proc;
5386            int oomAdj;
5387            synchronized (this) {
5388                synchronized (mPidsSelfLocked) {
5389                    proc = mPidsSelfLocked.get(pids[i]);
5390                    oomAdj = proc != null ? proc.setAdj : 0;
5391                }
5392            }
5393            infos[i] = new Debug.MemoryInfo();
5394            Debug.getMemoryInfo(pids[i], infos[i]);
5395            if (proc != null) {
5396                synchronized (this) {
5397                    if (proc.thread != null && proc.setAdj == oomAdj) {
5398                        // Record this for posterity if the process has been stable.
5399                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5400                                infos[i].getTotalUss(), false, proc.pkgList);
5401                    }
5402                }
5403            }
5404        }
5405        return infos;
5406    }
5407
5408    @Override
5409    public long[] getProcessPss(int[] pids) {
5410        enforceNotIsolatedCaller("getProcessPss");
5411        long[] pss = new long[pids.length];
5412        for (int i=pids.length-1; i>=0; i--) {
5413            ProcessRecord proc;
5414            int oomAdj;
5415            synchronized (this) {
5416                synchronized (mPidsSelfLocked) {
5417                    proc = mPidsSelfLocked.get(pids[i]);
5418                    oomAdj = proc != null ? proc.setAdj : 0;
5419                }
5420            }
5421            long[] tmpUss = new long[1];
5422            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5423            if (proc != null) {
5424                synchronized (this) {
5425                    if (proc.thread != null && proc.setAdj == oomAdj) {
5426                        // Record this for posterity if the process has been stable.
5427                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5428                    }
5429                }
5430            }
5431        }
5432        return pss;
5433    }
5434
5435    @Override
5436    public void killApplicationProcess(String processName, int uid) {
5437        if (processName == null) {
5438            return;
5439        }
5440
5441        int callerUid = Binder.getCallingUid();
5442        // Only the system server can kill an application
5443        if (callerUid == Process.SYSTEM_UID) {
5444            synchronized (this) {
5445                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5446                if (app != null && app.thread != null) {
5447                    try {
5448                        app.thread.scheduleSuicide();
5449                    } catch (RemoteException e) {
5450                        // If the other end already died, then our work here is done.
5451                    }
5452                } else {
5453                    Slog.w(TAG, "Process/uid not found attempting kill of "
5454                            + processName + " / " + uid);
5455                }
5456            }
5457        } else {
5458            throw new SecurityException(callerUid + " cannot kill app process: " +
5459                    processName);
5460        }
5461    }
5462
5463    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5464        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5465                false, true, false, false, UserHandle.getUserId(uid), reason);
5466        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5467                Uri.fromParts("package", packageName, null));
5468        if (!mProcessesReady) {
5469            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5470                    | Intent.FLAG_RECEIVER_FOREGROUND);
5471        }
5472        intent.putExtra(Intent.EXTRA_UID, uid);
5473        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5474        broadcastIntentLocked(null, null, intent,
5475                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5476                false, false,
5477                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5478    }
5479
5480    private void forceStopUserLocked(int userId, String reason) {
5481        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5482        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5483        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5484                | Intent.FLAG_RECEIVER_FOREGROUND);
5485        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5486        broadcastIntentLocked(null, null, intent,
5487                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5488                false, false,
5489                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5490    }
5491
5492    private final boolean killPackageProcessesLocked(String packageName, int appId,
5493            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5494            boolean doit, boolean evenPersistent, String reason) {
5495        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5496
5497        // Remove all processes this package may have touched: all with the
5498        // same UID (except for the system or root user), and all whose name
5499        // matches the package name.
5500        final int NP = mProcessNames.getMap().size();
5501        for (int ip=0; ip<NP; ip++) {
5502            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5503            final int NA = apps.size();
5504            for (int ia=0; ia<NA; ia++) {
5505                ProcessRecord app = apps.valueAt(ia);
5506                if (app.persistent && !evenPersistent) {
5507                    // we don't kill persistent processes
5508                    continue;
5509                }
5510                if (app.removed) {
5511                    if (doit) {
5512                        procs.add(app);
5513                    }
5514                    continue;
5515                }
5516
5517                // Skip process if it doesn't meet our oom adj requirement.
5518                if (app.setAdj < minOomAdj) {
5519                    continue;
5520                }
5521
5522                // If no package is specified, we call all processes under the
5523                // give user id.
5524                if (packageName == null) {
5525                    if (app.userId != userId) {
5526                        continue;
5527                    }
5528                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5529                        continue;
5530                    }
5531                // Package has been specified, we want to hit all processes
5532                // that match it.  We need to qualify this by the processes
5533                // that are running under the specified app and user ID.
5534                } else {
5535                    final boolean isDep = app.pkgDeps != null
5536                            && app.pkgDeps.contains(packageName);
5537                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5538                        continue;
5539                    }
5540                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5541                        continue;
5542                    }
5543                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5544                        continue;
5545                    }
5546                }
5547
5548                // Process has passed all conditions, kill it!
5549                if (!doit) {
5550                    return true;
5551                }
5552                app.removed = true;
5553                procs.add(app);
5554            }
5555        }
5556
5557        int N = procs.size();
5558        for (int i=0; i<N; i++) {
5559            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5560        }
5561        updateOomAdjLocked();
5562        return N > 0;
5563    }
5564
5565    private final boolean forceStopPackageLocked(String name, int appId,
5566            boolean callerWillRestart, boolean purgeCache, boolean doit,
5567            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5568        int i;
5569        int N;
5570
5571        if (userId == UserHandle.USER_ALL && name == null) {
5572            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5573        }
5574
5575        if (appId < 0 && name != null) {
5576            try {
5577                appId = UserHandle.getAppId(
5578                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5579            } catch (RemoteException e) {
5580            }
5581        }
5582
5583        if (doit) {
5584            if (name != null) {
5585                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5586                        + " user=" + userId + ": " + reason);
5587            } else {
5588                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5589            }
5590
5591            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5592            for (int ip=pmap.size()-1; ip>=0; ip--) {
5593                SparseArray<Long> ba = pmap.valueAt(ip);
5594                for (i=ba.size()-1; i>=0; i--) {
5595                    boolean remove = false;
5596                    final int entUid = ba.keyAt(i);
5597                    if (name != null) {
5598                        if (userId == UserHandle.USER_ALL) {
5599                            if (UserHandle.getAppId(entUid) == appId) {
5600                                remove = true;
5601                            }
5602                        } else {
5603                            if (entUid == UserHandle.getUid(userId, appId)) {
5604                                remove = true;
5605                            }
5606                        }
5607                    } else if (UserHandle.getUserId(entUid) == userId) {
5608                        remove = true;
5609                    }
5610                    if (remove) {
5611                        ba.removeAt(i);
5612                    }
5613                }
5614                if (ba.size() == 0) {
5615                    pmap.removeAt(ip);
5616                }
5617            }
5618        }
5619
5620        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5621                -100, callerWillRestart, true, doit, evenPersistent,
5622                name == null ? ("stop user " + userId) : ("stop " + name));
5623
5624        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5625            if (!doit) {
5626                return true;
5627            }
5628            didSomething = true;
5629        }
5630
5631        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5632            if (!doit) {
5633                return true;
5634            }
5635            didSomething = true;
5636        }
5637
5638        if (name == null) {
5639            // Remove all sticky broadcasts from this user.
5640            mStickyBroadcasts.remove(userId);
5641        }
5642
5643        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5644        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5645                userId, providers)) {
5646            if (!doit) {
5647                return true;
5648            }
5649            didSomething = true;
5650        }
5651        N = providers.size();
5652        for (i=0; i<N; i++) {
5653            removeDyingProviderLocked(null, providers.get(i), true);
5654        }
5655
5656        // Remove transient permissions granted from/to this package/user
5657        removeUriPermissionsForPackageLocked(name, userId, false);
5658
5659        if (name == null || uninstalling) {
5660            // Remove pending intents.  For now we only do this when force
5661            // stopping users, because we have some problems when doing this
5662            // for packages -- app widgets are not currently cleaned up for
5663            // such packages, so they can be left with bad pending intents.
5664            if (mIntentSenderRecords.size() > 0) {
5665                Iterator<WeakReference<PendingIntentRecord>> it
5666                        = mIntentSenderRecords.values().iterator();
5667                while (it.hasNext()) {
5668                    WeakReference<PendingIntentRecord> wpir = it.next();
5669                    if (wpir == null) {
5670                        it.remove();
5671                        continue;
5672                    }
5673                    PendingIntentRecord pir = wpir.get();
5674                    if (pir == null) {
5675                        it.remove();
5676                        continue;
5677                    }
5678                    if (name == null) {
5679                        // Stopping user, remove all objects for the user.
5680                        if (pir.key.userId != userId) {
5681                            // Not the same user, skip it.
5682                            continue;
5683                        }
5684                    } else {
5685                        if (UserHandle.getAppId(pir.uid) != appId) {
5686                            // Different app id, skip it.
5687                            continue;
5688                        }
5689                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5690                            // Different user, skip it.
5691                            continue;
5692                        }
5693                        if (!pir.key.packageName.equals(name)) {
5694                            // Different package, skip it.
5695                            continue;
5696                        }
5697                    }
5698                    if (!doit) {
5699                        return true;
5700                    }
5701                    didSomething = true;
5702                    it.remove();
5703                    pir.canceled = true;
5704                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5705                        pir.key.activity.pendingResults.remove(pir.ref);
5706                    }
5707                }
5708            }
5709        }
5710
5711        if (doit) {
5712            if (purgeCache && name != null) {
5713                AttributeCache ac = AttributeCache.instance();
5714                if (ac != null) {
5715                    ac.removePackage(name);
5716                }
5717            }
5718            if (mBooted) {
5719                mStackSupervisor.resumeTopActivitiesLocked();
5720                mStackSupervisor.scheduleIdleLocked();
5721            }
5722        }
5723
5724        return didSomething;
5725    }
5726
5727    private final boolean removeProcessLocked(ProcessRecord app,
5728            boolean callerWillRestart, boolean allowRestart, String reason) {
5729        final String name = app.processName;
5730        final int uid = app.uid;
5731        if (DEBUG_PROCESSES) Slog.d(
5732            TAG, "Force removing proc " + app.toShortString() + " (" + name
5733            + "/" + uid + ")");
5734
5735        mProcessNames.remove(name, uid);
5736        mIsolatedProcesses.remove(app.uid);
5737        if (mHeavyWeightProcess == app) {
5738            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5739                    mHeavyWeightProcess.userId, 0));
5740            mHeavyWeightProcess = null;
5741        }
5742        boolean needRestart = false;
5743        if (app.pid > 0 && app.pid != MY_PID) {
5744            int pid = app.pid;
5745            synchronized (mPidsSelfLocked) {
5746                mPidsSelfLocked.remove(pid);
5747                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5748            }
5749            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5750            if (app.isolated) {
5751                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5752            }
5753            app.kill(reason, true);
5754            handleAppDiedLocked(app, true, allowRestart);
5755            removeLruProcessLocked(app);
5756
5757            if (app.persistent && !app.isolated) {
5758                if (!callerWillRestart) {
5759                    addAppLocked(app.info, false, null /* ABI override */);
5760                } else {
5761                    needRestart = true;
5762                }
5763            }
5764        } else {
5765            mRemovedProcesses.add(app);
5766        }
5767
5768        return needRestart;
5769    }
5770
5771    private final void processStartTimedOutLocked(ProcessRecord app) {
5772        final int pid = app.pid;
5773        boolean gone = false;
5774        synchronized (mPidsSelfLocked) {
5775            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5776            if (knownApp != null && knownApp.thread == null) {
5777                mPidsSelfLocked.remove(pid);
5778                gone = true;
5779            }
5780        }
5781
5782        if (gone) {
5783            Slog.w(TAG, "Process " + app + " failed to attach");
5784            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5785                    pid, app.uid, app.processName);
5786            mProcessNames.remove(app.processName, app.uid);
5787            mIsolatedProcesses.remove(app.uid);
5788            if (mHeavyWeightProcess == app) {
5789                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5790                        mHeavyWeightProcess.userId, 0));
5791                mHeavyWeightProcess = null;
5792            }
5793            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5794            if (app.isolated) {
5795                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5796            }
5797            // Take care of any launching providers waiting for this process.
5798            checkAppInLaunchingProvidersLocked(app, true);
5799            // Take care of any services that are waiting for the process.
5800            mServices.processStartTimedOutLocked(app);
5801            app.kill("start timeout", true);
5802            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5803                Slog.w(TAG, "Unattached app died before backup, skipping");
5804                try {
5805                    IBackupManager bm = IBackupManager.Stub.asInterface(
5806                            ServiceManager.getService(Context.BACKUP_SERVICE));
5807                    bm.agentDisconnected(app.info.packageName);
5808                } catch (RemoteException e) {
5809                    // Can't happen; the backup manager is local
5810                }
5811            }
5812            if (isPendingBroadcastProcessLocked(pid)) {
5813                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5814                skipPendingBroadcastLocked(pid);
5815            }
5816        } else {
5817            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5818        }
5819    }
5820
5821    private final boolean attachApplicationLocked(IApplicationThread thread,
5822            int pid) {
5823
5824        // Find the application record that is being attached...  either via
5825        // the pid if we are running in multiple processes, or just pull the
5826        // next app record if we are emulating process with anonymous threads.
5827        ProcessRecord app;
5828        if (pid != MY_PID && pid >= 0) {
5829            synchronized (mPidsSelfLocked) {
5830                app = mPidsSelfLocked.get(pid);
5831            }
5832        } else {
5833            app = null;
5834        }
5835
5836        if (app == null) {
5837            Slog.w(TAG, "No pending application record for pid " + pid
5838                    + " (IApplicationThread " + thread + "); dropping process");
5839            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5840            if (pid > 0 && pid != MY_PID) {
5841                Process.killProcessQuiet(pid);
5842                //TODO: Process.killProcessGroup(app.info.uid, pid);
5843            } else {
5844                try {
5845                    thread.scheduleExit();
5846                } catch (Exception e) {
5847                    // Ignore exceptions.
5848                }
5849            }
5850            return false;
5851        }
5852
5853        // If this application record is still attached to a previous
5854        // process, clean it up now.
5855        if (app.thread != null) {
5856            handleAppDiedLocked(app, true, true);
5857        }
5858
5859        // Tell the process all about itself.
5860
5861        if (localLOGV) Slog.v(
5862                TAG, "Binding process pid " + pid + " to record " + app);
5863
5864        final String processName = app.processName;
5865        try {
5866            AppDeathRecipient adr = new AppDeathRecipient(
5867                    app, pid, thread);
5868            thread.asBinder().linkToDeath(adr, 0);
5869            app.deathRecipient = adr;
5870        } catch (RemoteException e) {
5871            app.resetPackageList(mProcessStats);
5872            startProcessLocked(app, "link fail", processName);
5873            return false;
5874        }
5875
5876        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5877
5878        app.makeActive(thread, mProcessStats);
5879        app.curAdj = app.setAdj = -100;
5880        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5881        app.forcingToForeground = null;
5882        updateProcessForegroundLocked(app, false, false);
5883        app.hasShownUi = false;
5884        app.debugging = false;
5885        app.cached = false;
5886        app.killedByAm = false;
5887
5888        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5889
5890        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5891        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5892
5893        if (!normalMode) {
5894            Slog.i(TAG, "Launching preboot mode app: " + app);
5895        }
5896
5897        if (localLOGV) Slog.v(
5898            TAG, "New app record " + app
5899            + " thread=" + thread.asBinder() + " pid=" + pid);
5900        try {
5901            int testMode = IApplicationThread.DEBUG_OFF;
5902            if (mDebugApp != null && mDebugApp.equals(processName)) {
5903                testMode = mWaitForDebugger
5904                    ? IApplicationThread.DEBUG_WAIT
5905                    : IApplicationThread.DEBUG_ON;
5906                app.debugging = true;
5907                if (mDebugTransient) {
5908                    mDebugApp = mOrigDebugApp;
5909                    mWaitForDebugger = mOrigWaitForDebugger;
5910                }
5911            }
5912            String profileFile = app.instrumentationProfileFile;
5913            ParcelFileDescriptor profileFd = null;
5914            int samplingInterval = 0;
5915            boolean profileAutoStop = false;
5916            if (mProfileApp != null && mProfileApp.equals(processName)) {
5917                mProfileProc = app;
5918                profileFile = mProfileFile;
5919                profileFd = mProfileFd;
5920                samplingInterval = mSamplingInterval;
5921                profileAutoStop = mAutoStopProfiler;
5922            }
5923            boolean enableOpenGlTrace = false;
5924            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5925                enableOpenGlTrace = true;
5926                mOpenGlTraceApp = null;
5927            }
5928
5929            // If the app is being launched for restore or full backup, set it up specially
5930            boolean isRestrictedBackupMode = false;
5931            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5932                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5933                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5934                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5935            }
5936
5937            ensurePackageDexOpt(app.instrumentationInfo != null
5938                    ? app.instrumentationInfo.packageName
5939                    : app.info.packageName);
5940            if (app.instrumentationClass != null) {
5941                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5942            }
5943            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5944                    + processName + " with config " + mConfiguration);
5945            ApplicationInfo appInfo = app.instrumentationInfo != null
5946                    ? app.instrumentationInfo : app.info;
5947            app.compat = compatibilityInfoForPackageLocked(appInfo);
5948            if (profileFd != null) {
5949                profileFd = profileFd.dup();
5950            }
5951            ProfilerInfo profilerInfo = profileFile == null ? null
5952                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5953            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5954                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5955                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5956                    isRestrictedBackupMode || !normalMode, app.persistent,
5957                    new Configuration(mConfiguration), app.compat,
5958                    getCommonServicesLocked(app.isolated),
5959                    mCoreSettingsObserver.getCoreSettingsLocked());
5960            updateLruProcessLocked(app, false, null);
5961            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5962        } catch (Exception e) {
5963            // todo: Yikes!  What should we do?  For now we will try to
5964            // start another process, but that could easily get us in
5965            // an infinite loop of restarting processes...
5966            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5967
5968            app.resetPackageList(mProcessStats);
5969            app.unlinkDeathRecipient();
5970            startProcessLocked(app, "bind fail", processName);
5971            return false;
5972        }
5973
5974        // Remove this record from the list of starting applications.
5975        mPersistentStartingProcesses.remove(app);
5976        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5977                "Attach application locked removing on hold: " + app);
5978        mProcessesOnHold.remove(app);
5979
5980        boolean badApp = false;
5981        boolean didSomething = false;
5982
5983        // See if the top visible activity is waiting to run in this process...
5984        if (normalMode) {
5985            try {
5986                if (mStackSupervisor.attachApplicationLocked(app)) {
5987                    didSomething = true;
5988                }
5989            } catch (Exception e) {
5990                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5991                badApp = true;
5992            }
5993        }
5994
5995        // Find any services that should be running in this process...
5996        if (!badApp) {
5997            try {
5998                didSomething |= mServices.attachApplicationLocked(app, processName);
5999            } catch (Exception e) {
6000                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6001                badApp = true;
6002            }
6003        }
6004
6005        // Check if a next-broadcast receiver is in this process...
6006        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6007            try {
6008                didSomething |= sendPendingBroadcastsLocked(app);
6009            } catch (Exception e) {
6010                // If the app died trying to launch the receiver we declare it 'bad'
6011                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6012                badApp = true;
6013            }
6014        }
6015
6016        // Check whether the next backup agent is in this process...
6017        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6018            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6019            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6020            try {
6021                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6022                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6023                        mBackupTarget.backupMode);
6024            } catch (Exception e) {
6025                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6026                badApp = true;
6027            }
6028        }
6029
6030        if (badApp) {
6031            app.kill("error during init", true);
6032            handleAppDiedLocked(app, false, true);
6033            return false;
6034        }
6035
6036        if (!didSomething) {
6037            updateOomAdjLocked();
6038        }
6039
6040        return true;
6041    }
6042
6043    @Override
6044    public final void attachApplication(IApplicationThread thread) {
6045        synchronized (this) {
6046            int callingPid = Binder.getCallingPid();
6047            final long origId = Binder.clearCallingIdentity();
6048            attachApplicationLocked(thread, callingPid);
6049            Binder.restoreCallingIdentity(origId);
6050        }
6051    }
6052
6053    @Override
6054    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6055        final long origId = Binder.clearCallingIdentity();
6056        synchronized (this) {
6057            ActivityStack stack = ActivityRecord.getStackLocked(token);
6058            if (stack != null) {
6059                ActivityRecord r =
6060                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6061                if (stopProfiling) {
6062                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6063                        try {
6064                            mProfileFd.close();
6065                        } catch (IOException e) {
6066                        }
6067                        clearProfilerLocked();
6068                    }
6069                }
6070            }
6071        }
6072        Binder.restoreCallingIdentity(origId);
6073    }
6074
6075    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6076        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6077                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6078    }
6079
6080    void enableScreenAfterBoot() {
6081        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6082                SystemClock.uptimeMillis());
6083        mWindowManager.enableScreenAfterBoot();
6084
6085        synchronized (this) {
6086            updateEventDispatchingLocked();
6087        }
6088    }
6089
6090    @Override
6091    public void showBootMessage(final CharSequence msg, final boolean always) {
6092        enforceNotIsolatedCaller("showBootMessage");
6093        mWindowManager.showBootMessage(msg, always);
6094    }
6095
6096    @Override
6097    public void keyguardWaitingForActivityDrawn() {
6098        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6099        final long token = Binder.clearCallingIdentity();
6100        try {
6101            synchronized (this) {
6102                if (DEBUG_LOCKSCREEN) logLockScreen("");
6103                mWindowManager.keyguardWaitingForActivityDrawn();
6104                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6105                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6106                    updateSleepIfNeededLocked();
6107                }
6108            }
6109        } finally {
6110            Binder.restoreCallingIdentity(token);
6111        }
6112    }
6113
6114    final void finishBooting() {
6115        synchronized (this) {
6116            if (!mBootAnimationComplete) {
6117                mCallFinishBooting = true;
6118                return;
6119            }
6120            mCallFinishBooting = false;
6121        }
6122
6123        ArraySet<String> completedIsas = new ArraySet<String>();
6124        for (String abi : Build.SUPPORTED_ABIS) {
6125            Process.establishZygoteConnectionForAbi(abi);
6126            final String instructionSet = VMRuntime.getInstructionSet(abi);
6127            if (!completedIsas.contains(instructionSet)) {
6128                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6129                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6130                }
6131                completedIsas.add(instructionSet);
6132            }
6133        }
6134
6135        IntentFilter pkgFilter = new IntentFilter();
6136        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6137        pkgFilter.addDataScheme("package");
6138        mContext.registerReceiver(new BroadcastReceiver() {
6139            @Override
6140            public void onReceive(Context context, Intent intent) {
6141                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6142                if (pkgs != null) {
6143                    for (String pkg : pkgs) {
6144                        synchronized (ActivityManagerService.this) {
6145                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6146                                    0, "finished booting")) {
6147                                setResultCode(Activity.RESULT_OK);
6148                                return;
6149                            }
6150                        }
6151                    }
6152                }
6153            }
6154        }, pkgFilter);
6155
6156        // Let system services know.
6157        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6158
6159        synchronized (this) {
6160            // Ensure that any processes we had put on hold are now started
6161            // up.
6162            final int NP = mProcessesOnHold.size();
6163            if (NP > 0) {
6164                ArrayList<ProcessRecord> procs =
6165                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6166                for (int ip=0; ip<NP; ip++) {
6167                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6168                            + procs.get(ip));
6169                    startProcessLocked(procs.get(ip), "on-hold", null);
6170                }
6171            }
6172
6173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6174                // Start looking for apps that are abusing wake locks.
6175                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6176                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6177                // Tell anyone interested that we are done booting!
6178                SystemProperties.set("sys.boot_completed", "1");
6179
6180                // And trigger dev.bootcomplete if we are not showing encryption progress
6181                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6182                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6183                    SystemProperties.set("dev.bootcomplete", "1");
6184                }
6185                for (int i=0; i<mStartedUsers.size(); i++) {
6186                    UserStartedState uss = mStartedUsers.valueAt(i);
6187                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6188                        uss.mState = UserStartedState.STATE_RUNNING;
6189                        final int userId = mStartedUsers.keyAt(i);
6190                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6191                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6192                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6193                        broadcastIntentLocked(null, null, intent, null,
6194                                new IIntentReceiver.Stub() {
6195                                    @Override
6196                                    public void performReceive(Intent intent, int resultCode,
6197                                            String data, Bundle extras, boolean ordered,
6198                                            boolean sticky, int sendingUser) {
6199                                        synchronized (ActivityManagerService.this) {
6200                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6201                                                    true, false);
6202                                        }
6203                                    }
6204                                },
6205                                0, null, null,
6206                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6207                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6208                                userId);
6209                    }
6210                }
6211                scheduleStartProfilesLocked();
6212            }
6213        }
6214    }
6215
6216    @Override
6217    public void bootAnimationComplete() {
6218        final boolean callFinishBooting;
6219        synchronized (this) {
6220            callFinishBooting = mCallFinishBooting;
6221            mBootAnimationComplete = true;
6222        }
6223        if (callFinishBooting) {
6224            finishBooting();
6225        }
6226    }
6227
6228    @Override
6229    public void systemBackupRestored() {
6230        synchronized (this) {
6231            if (mSystemReady) {
6232                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6233            } else {
6234                Slog.w(TAG, "System backup restored before system is ready");
6235            }
6236        }
6237    }
6238
6239    final void ensureBootCompleted() {
6240        boolean booting;
6241        boolean enableScreen;
6242        synchronized (this) {
6243            booting = mBooting;
6244            mBooting = false;
6245            enableScreen = !mBooted;
6246            mBooted = true;
6247        }
6248
6249        if (booting) {
6250            finishBooting();
6251        }
6252
6253        if (enableScreen) {
6254            enableScreenAfterBoot();
6255        }
6256    }
6257
6258    @Override
6259    public final void activityResumed(IBinder token) {
6260        final long origId = Binder.clearCallingIdentity();
6261        synchronized(this) {
6262            ActivityStack stack = ActivityRecord.getStackLocked(token);
6263            if (stack != null) {
6264                ActivityRecord.activityResumedLocked(token);
6265            }
6266        }
6267        Binder.restoreCallingIdentity(origId);
6268    }
6269
6270    @Override
6271    public final void activityPaused(IBinder token) {
6272        final long origId = Binder.clearCallingIdentity();
6273        synchronized(this) {
6274            ActivityStack stack = ActivityRecord.getStackLocked(token);
6275            if (stack != null) {
6276                stack.activityPausedLocked(token, false);
6277            }
6278        }
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    @Override
6283    public final void activityStopped(IBinder token, Bundle icicle,
6284            PersistableBundle persistentState, CharSequence description) {
6285        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6286
6287        // Refuse possible leaked file descriptors
6288        if (icicle != null && icicle.hasFileDescriptors()) {
6289            throw new IllegalArgumentException("File descriptors passed in Bundle");
6290        }
6291
6292        final long origId = Binder.clearCallingIdentity();
6293
6294        synchronized (this) {
6295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6296            if (r != null) {
6297                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6298            }
6299        }
6300
6301        trimApplications();
6302
6303        Binder.restoreCallingIdentity(origId);
6304    }
6305
6306    @Override
6307    public final void activityDestroyed(IBinder token) {
6308        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6309        synchronized (this) {
6310            ActivityStack stack = ActivityRecord.getStackLocked(token);
6311            if (stack != null) {
6312                stack.activityDestroyedLocked(token);
6313            }
6314        }
6315    }
6316
6317    @Override
6318    public final void backgroundResourcesReleased(IBinder token) {
6319        final long origId = Binder.clearCallingIdentity();
6320        try {
6321            synchronized (this) {
6322                ActivityStack stack = ActivityRecord.getStackLocked(token);
6323                if (stack != null) {
6324                    stack.backgroundResourcesReleased();
6325                }
6326            }
6327        } finally {
6328            Binder.restoreCallingIdentity(origId);
6329        }
6330    }
6331
6332    @Override
6333    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6334        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6335    }
6336
6337    @Override
6338    public final void notifyEnterAnimationComplete(IBinder token) {
6339        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6340    }
6341
6342    @Override
6343    public String getCallingPackage(IBinder token) {
6344        synchronized (this) {
6345            ActivityRecord r = getCallingRecordLocked(token);
6346            return r != null ? r.info.packageName : null;
6347        }
6348    }
6349
6350    @Override
6351    public ComponentName getCallingActivity(IBinder token) {
6352        synchronized (this) {
6353            ActivityRecord r = getCallingRecordLocked(token);
6354            return r != null ? r.intent.getComponent() : null;
6355        }
6356    }
6357
6358    private ActivityRecord getCallingRecordLocked(IBinder token) {
6359        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6360        if (r == null) {
6361            return null;
6362        }
6363        return r.resultTo;
6364    }
6365
6366    @Override
6367    public ComponentName getActivityClassForToken(IBinder token) {
6368        synchronized(this) {
6369            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6370            if (r == null) {
6371                return null;
6372            }
6373            return r.intent.getComponent();
6374        }
6375    }
6376
6377    @Override
6378    public String getPackageForToken(IBinder token) {
6379        synchronized(this) {
6380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6381            if (r == null) {
6382                return null;
6383            }
6384            return r.packageName;
6385        }
6386    }
6387
6388    @Override
6389    public IIntentSender getIntentSender(int type,
6390            String packageName, IBinder token, String resultWho,
6391            int requestCode, Intent[] intents, String[] resolvedTypes,
6392            int flags, Bundle options, int userId) {
6393        enforceNotIsolatedCaller("getIntentSender");
6394        // Refuse possible leaked file descriptors
6395        if (intents != null) {
6396            if (intents.length < 1) {
6397                throw new IllegalArgumentException("Intents array length must be >= 1");
6398            }
6399            for (int i=0; i<intents.length; i++) {
6400                Intent intent = intents[i];
6401                if (intent != null) {
6402                    if (intent.hasFileDescriptors()) {
6403                        throw new IllegalArgumentException("File descriptors passed in Intent");
6404                    }
6405                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6406                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6407                        throw new IllegalArgumentException(
6408                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6409                    }
6410                    intents[i] = new Intent(intent);
6411                }
6412            }
6413            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6414                throw new IllegalArgumentException(
6415                        "Intent array length does not match resolvedTypes length");
6416            }
6417        }
6418        if (options != null) {
6419            if (options.hasFileDescriptors()) {
6420                throw new IllegalArgumentException("File descriptors passed in options");
6421            }
6422        }
6423
6424        synchronized(this) {
6425            int callingUid = Binder.getCallingUid();
6426            int origUserId = userId;
6427            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6428                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6429                    ALLOW_NON_FULL, "getIntentSender", null);
6430            if (origUserId == UserHandle.USER_CURRENT) {
6431                // We don't want to evaluate this until the pending intent is
6432                // actually executed.  However, we do want to always do the
6433                // security checking for it above.
6434                userId = UserHandle.USER_CURRENT;
6435            }
6436            try {
6437                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6438                    int uid = AppGlobals.getPackageManager()
6439                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6440                    if (!UserHandle.isSameApp(callingUid, uid)) {
6441                        String msg = "Permission Denial: getIntentSender() from pid="
6442                            + Binder.getCallingPid()
6443                            + ", uid=" + Binder.getCallingUid()
6444                            + ", (need uid=" + uid + ")"
6445                            + " is not allowed to send as package " + packageName;
6446                        Slog.w(TAG, msg);
6447                        throw new SecurityException(msg);
6448                    }
6449                }
6450
6451                return getIntentSenderLocked(type, packageName, callingUid, userId,
6452                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6453
6454            } catch (RemoteException e) {
6455                throw new SecurityException(e);
6456            }
6457        }
6458    }
6459
6460    IIntentSender getIntentSenderLocked(int type, String packageName,
6461            int callingUid, int userId, IBinder token, String resultWho,
6462            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6463            Bundle options) {
6464        if (DEBUG_MU)
6465            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6466        ActivityRecord activity = null;
6467        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6468            activity = ActivityRecord.isInStackLocked(token);
6469            if (activity == null) {
6470                return null;
6471            }
6472            if (activity.finishing) {
6473                return null;
6474            }
6475        }
6476
6477        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6478        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6479        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6480        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6481                |PendingIntent.FLAG_UPDATE_CURRENT);
6482
6483        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6484                type, packageName, activity, resultWho,
6485                requestCode, intents, resolvedTypes, flags, options, userId);
6486        WeakReference<PendingIntentRecord> ref;
6487        ref = mIntentSenderRecords.get(key);
6488        PendingIntentRecord rec = ref != null ? ref.get() : null;
6489        if (rec != null) {
6490            if (!cancelCurrent) {
6491                if (updateCurrent) {
6492                    if (rec.key.requestIntent != null) {
6493                        rec.key.requestIntent.replaceExtras(intents != null ?
6494                                intents[intents.length - 1] : null);
6495                    }
6496                    if (intents != null) {
6497                        intents[intents.length-1] = rec.key.requestIntent;
6498                        rec.key.allIntents = intents;
6499                        rec.key.allResolvedTypes = resolvedTypes;
6500                    } else {
6501                        rec.key.allIntents = null;
6502                        rec.key.allResolvedTypes = null;
6503                    }
6504                }
6505                return rec;
6506            }
6507            rec.canceled = true;
6508            mIntentSenderRecords.remove(key);
6509        }
6510        if (noCreate) {
6511            return rec;
6512        }
6513        rec = new PendingIntentRecord(this, key, callingUid);
6514        mIntentSenderRecords.put(key, rec.ref);
6515        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6516            if (activity.pendingResults == null) {
6517                activity.pendingResults
6518                        = new HashSet<WeakReference<PendingIntentRecord>>();
6519            }
6520            activity.pendingResults.add(rec.ref);
6521        }
6522        return rec;
6523    }
6524
6525    @Override
6526    public void cancelIntentSender(IIntentSender sender) {
6527        if (!(sender instanceof PendingIntentRecord)) {
6528            return;
6529        }
6530        synchronized(this) {
6531            PendingIntentRecord rec = (PendingIntentRecord)sender;
6532            try {
6533                int uid = AppGlobals.getPackageManager()
6534                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6535                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6536                    String msg = "Permission Denial: cancelIntentSender() from pid="
6537                        + Binder.getCallingPid()
6538                        + ", uid=" + Binder.getCallingUid()
6539                        + " is not allowed to cancel packges "
6540                        + rec.key.packageName;
6541                    Slog.w(TAG, msg);
6542                    throw new SecurityException(msg);
6543                }
6544            } catch (RemoteException e) {
6545                throw new SecurityException(e);
6546            }
6547            cancelIntentSenderLocked(rec, true);
6548        }
6549    }
6550
6551    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6552        rec.canceled = true;
6553        mIntentSenderRecords.remove(rec.key);
6554        if (cleanActivity && rec.key.activity != null) {
6555            rec.key.activity.pendingResults.remove(rec.ref);
6556        }
6557    }
6558
6559    @Override
6560    public String getPackageForIntentSender(IIntentSender pendingResult) {
6561        if (!(pendingResult instanceof PendingIntentRecord)) {
6562            return null;
6563        }
6564        try {
6565            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6566            return res.key.packageName;
6567        } catch (ClassCastException e) {
6568        }
6569        return null;
6570    }
6571
6572    @Override
6573    public int getUidForIntentSender(IIntentSender sender) {
6574        if (sender instanceof PendingIntentRecord) {
6575            try {
6576                PendingIntentRecord res = (PendingIntentRecord)sender;
6577                return res.uid;
6578            } catch (ClassCastException e) {
6579            }
6580        }
6581        return -1;
6582    }
6583
6584    @Override
6585    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6586        if (!(pendingResult instanceof PendingIntentRecord)) {
6587            return false;
6588        }
6589        try {
6590            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6591            if (res.key.allIntents == null) {
6592                return false;
6593            }
6594            for (int i=0; i<res.key.allIntents.length; i++) {
6595                Intent intent = res.key.allIntents[i];
6596                if (intent.getPackage() != null && intent.getComponent() != null) {
6597                    return false;
6598                }
6599            }
6600            return true;
6601        } catch (ClassCastException e) {
6602        }
6603        return false;
6604    }
6605
6606    @Override
6607    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6608        if (!(pendingResult instanceof PendingIntentRecord)) {
6609            return false;
6610        }
6611        try {
6612            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6613            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6614                return true;
6615            }
6616            return false;
6617        } catch (ClassCastException e) {
6618        }
6619        return false;
6620    }
6621
6622    @Override
6623    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6624        if (!(pendingResult instanceof PendingIntentRecord)) {
6625            return null;
6626        }
6627        try {
6628            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6629            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6630        } catch (ClassCastException e) {
6631        }
6632        return null;
6633    }
6634
6635    @Override
6636    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6637        if (!(pendingResult instanceof PendingIntentRecord)) {
6638            return null;
6639        }
6640        try {
6641            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6642            Intent intent = res.key.requestIntent;
6643            if (intent != null) {
6644                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6645                        || res.lastTagPrefix.equals(prefix))) {
6646                    return res.lastTag;
6647                }
6648                res.lastTagPrefix = prefix;
6649                StringBuilder sb = new StringBuilder(128);
6650                if (prefix != null) {
6651                    sb.append(prefix);
6652                }
6653                if (intent.getAction() != null) {
6654                    sb.append(intent.getAction());
6655                } else if (intent.getComponent() != null) {
6656                    intent.getComponent().appendShortString(sb);
6657                } else {
6658                    sb.append("?");
6659                }
6660                return res.lastTag = sb.toString();
6661            }
6662        } catch (ClassCastException e) {
6663        }
6664        return null;
6665    }
6666
6667    @Override
6668    public void setProcessLimit(int max) {
6669        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6670                "setProcessLimit()");
6671        synchronized (this) {
6672            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6673            mProcessLimitOverride = max;
6674        }
6675        trimApplications();
6676    }
6677
6678    @Override
6679    public int getProcessLimit() {
6680        synchronized (this) {
6681            return mProcessLimitOverride;
6682        }
6683    }
6684
6685    void foregroundTokenDied(ForegroundToken token) {
6686        synchronized (ActivityManagerService.this) {
6687            synchronized (mPidsSelfLocked) {
6688                ForegroundToken cur
6689                    = mForegroundProcesses.get(token.pid);
6690                if (cur != token) {
6691                    return;
6692                }
6693                mForegroundProcesses.remove(token.pid);
6694                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6695                if (pr == null) {
6696                    return;
6697                }
6698                pr.forcingToForeground = null;
6699                updateProcessForegroundLocked(pr, false, false);
6700            }
6701            updateOomAdjLocked();
6702        }
6703    }
6704
6705    @Override
6706    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6707        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6708                "setProcessForeground()");
6709        synchronized(this) {
6710            boolean changed = false;
6711
6712            synchronized (mPidsSelfLocked) {
6713                ProcessRecord pr = mPidsSelfLocked.get(pid);
6714                if (pr == null && isForeground) {
6715                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6716                    return;
6717                }
6718                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6719                if (oldToken != null) {
6720                    oldToken.token.unlinkToDeath(oldToken, 0);
6721                    mForegroundProcesses.remove(pid);
6722                    if (pr != null) {
6723                        pr.forcingToForeground = null;
6724                    }
6725                    changed = true;
6726                }
6727                if (isForeground && token != null) {
6728                    ForegroundToken newToken = new ForegroundToken() {
6729                        @Override
6730                        public void binderDied() {
6731                            foregroundTokenDied(this);
6732                        }
6733                    };
6734                    newToken.pid = pid;
6735                    newToken.token = token;
6736                    try {
6737                        token.linkToDeath(newToken, 0);
6738                        mForegroundProcesses.put(pid, newToken);
6739                        pr.forcingToForeground = token;
6740                        changed = true;
6741                    } catch (RemoteException e) {
6742                        // If the process died while doing this, we will later
6743                        // do the cleanup with the process death link.
6744                    }
6745                }
6746            }
6747
6748            if (changed) {
6749                updateOomAdjLocked();
6750            }
6751        }
6752    }
6753
6754    // =========================================================
6755    // PERMISSIONS
6756    // =========================================================
6757
6758    static class PermissionController extends IPermissionController.Stub {
6759        ActivityManagerService mActivityManagerService;
6760        PermissionController(ActivityManagerService activityManagerService) {
6761            mActivityManagerService = activityManagerService;
6762        }
6763
6764        @Override
6765        public boolean checkPermission(String permission, int pid, int uid) {
6766            return mActivityManagerService.checkPermission(permission, pid,
6767                    uid) == PackageManager.PERMISSION_GRANTED;
6768        }
6769    }
6770
6771    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6772        @Override
6773        public int checkComponentPermission(String permission, int pid, int uid,
6774                int owningUid, boolean exported) {
6775            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6776                    owningUid, exported);
6777        }
6778
6779        @Override
6780        public Object getAMSLock() {
6781            return ActivityManagerService.this;
6782        }
6783    }
6784
6785    /**
6786     * This can be called with or without the global lock held.
6787     */
6788    int checkComponentPermission(String permission, int pid, int uid,
6789            int owningUid, boolean exported) {
6790        if (pid == MY_PID) {
6791            return PackageManager.PERMISSION_GRANTED;
6792        }
6793        return ActivityManager.checkComponentPermission(permission, uid,
6794                owningUid, exported);
6795    }
6796
6797    /**
6798     * As the only public entry point for permissions checking, this method
6799     * can enforce the semantic that requesting a check on a null global
6800     * permission is automatically denied.  (Internally a null permission
6801     * string is used when calling {@link #checkComponentPermission} in cases
6802     * when only uid-based security is needed.)
6803     *
6804     * This can be called with or without the global lock held.
6805     */
6806    @Override
6807    public int checkPermission(String permission, int pid, int uid) {
6808        if (permission == null) {
6809            return PackageManager.PERMISSION_DENIED;
6810        }
6811        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6812    }
6813
6814    @Override
6815    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6816        if (permission == null) {
6817            return PackageManager.PERMISSION_DENIED;
6818        }
6819
6820        // We might be performing an operation on behalf of an indirect binder
6821        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6822        // client identity accordingly before proceeding.
6823        Identity tlsIdentity = sCallerIdentity.get();
6824        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6825            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6826                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6827            uid = tlsIdentity.uid;
6828            pid = tlsIdentity.pid;
6829        }
6830
6831        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6832    }
6833
6834    /**
6835     * Binder IPC calls go through the public entry point.
6836     * This can be called with or without the global lock held.
6837     */
6838    int checkCallingPermission(String permission) {
6839        return checkPermission(permission,
6840                Binder.getCallingPid(),
6841                UserHandle.getAppId(Binder.getCallingUid()));
6842    }
6843
6844    /**
6845     * This can be called with or without the global lock held.
6846     */
6847    void enforceCallingPermission(String permission, String func) {
6848        if (checkCallingPermission(permission)
6849                == PackageManager.PERMISSION_GRANTED) {
6850            return;
6851        }
6852
6853        String msg = "Permission Denial: " + func + " from pid="
6854                + Binder.getCallingPid()
6855                + ", uid=" + Binder.getCallingUid()
6856                + " requires " + permission;
6857        Slog.w(TAG, msg);
6858        throw new SecurityException(msg);
6859    }
6860
6861    /**
6862     * Determine if UID is holding permissions required to access {@link Uri} in
6863     * the given {@link ProviderInfo}. Final permission checking is always done
6864     * in {@link ContentProvider}.
6865     */
6866    private final boolean checkHoldingPermissionsLocked(
6867            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6868        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6869                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6870        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6871            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6872                    != PERMISSION_GRANTED) {
6873                return false;
6874            }
6875        }
6876        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6877    }
6878
6879    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6880            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6881        if (pi.applicationInfo.uid == uid) {
6882            return true;
6883        } else if (!pi.exported) {
6884            return false;
6885        }
6886
6887        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6888        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6889        try {
6890            // check if target holds top-level <provider> permissions
6891            if (!readMet && pi.readPermission != null && considerUidPermissions
6892                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6893                readMet = true;
6894            }
6895            if (!writeMet && pi.writePermission != null && considerUidPermissions
6896                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6897                writeMet = true;
6898            }
6899
6900            // track if unprotected read/write is allowed; any denied
6901            // <path-permission> below removes this ability
6902            boolean allowDefaultRead = pi.readPermission == null;
6903            boolean allowDefaultWrite = pi.writePermission == null;
6904
6905            // check if target holds any <path-permission> that match uri
6906            final PathPermission[] pps = pi.pathPermissions;
6907            if (pps != null) {
6908                final String path = grantUri.uri.getPath();
6909                int i = pps.length;
6910                while (i > 0 && (!readMet || !writeMet)) {
6911                    i--;
6912                    PathPermission pp = pps[i];
6913                    if (pp.match(path)) {
6914                        if (!readMet) {
6915                            final String pprperm = pp.getReadPermission();
6916                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6917                                    + pprperm + " for " + pp.getPath()
6918                                    + ": match=" + pp.match(path)
6919                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6920                            if (pprperm != null) {
6921                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6922                                        == PERMISSION_GRANTED) {
6923                                    readMet = true;
6924                                } else {
6925                                    allowDefaultRead = false;
6926                                }
6927                            }
6928                        }
6929                        if (!writeMet) {
6930                            final String ppwperm = pp.getWritePermission();
6931                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6932                                    + ppwperm + " for " + pp.getPath()
6933                                    + ": match=" + pp.match(path)
6934                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6935                            if (ppwperm != null) {
6936                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6937                                        == PERMISSION_GRANTED) {
6938                                    writeMet = true;
6939                                } else {
6940                                    allowDefaultWrite = false;
6941                                }
6942                            }
6943                        }
6944                    }
6945                }
6946            }
6947
6948            // grant unprotected <provider> read/write, if not blocked by
6949            // <path-permission> above
6950            if (allowDefaultRead) readMet = true;
6951            if (allowDefaultWrite) writeMet = true;
6952
6953        } catch (RemoteException e) {
6954            return false;
6955        }
6956
6957        return readMet && writeMet;
6958    }
6959
6960    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6961        ProviderInfo pi = null;
6962        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6963        if (cpr != null) {
6964            pi = cpr.info;
6965        } else {
6966            try {
6967                pi = AppGlobals.getPackageManager().resolveContentProvider(
6968                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6969            } catch (RemoteException ex) {
6970            }
6971        }
6972        return pi;
6973    }
6974
6975    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6976        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6977        if (targetUris != null) {
6978            return targetUris.get(grantUri);
6979        }
6980        return null;
6981    }
6982
6983    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6984            String targetPkg, int targetUid, GrantUri grantUri) {
6985        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6986        if (targetUris == null) {
6987            targetUris = Maps.newArrayMap();
6988            mGrantedUriPermissions.put(targetUid, targetUris);
6989        }
6990
6991        UriPermission perm = targetUris.get(grantUri);
6992        if (perm == null) {
6993            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6994            targetUris.put(grantUri, perm);
6995        }
6996
6997        return perm;
6998    }
6999
7000    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7001            final int modeFlags) {
7002        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7003        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7004                : UriPermission.STRENGTH_OWNED;
7005
7006        // Root gets to do everything.
7007        if (uid == 0) {
7008            return true;
7009        }
7010
7011        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7012        if (perms == null) return false;
7013
7014        // First look for exact match
7015        final UriPermission exactPerm = perms.get(grantUri);
7016        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7017            return true;
7018        }
7019
7020        // No exact match, look for prefixes
7021        final int N = perms.size();
7022        for (int i = 0; i < N; i++) {
7023            final UriPermission perm = perms.valueAt(i);
7024            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7025                    && perm.getStrength(modeFlags) >= minStrength) {
7026                return true;
7027            }
7028        }
7029
7030        return false;
7031    }
7032
7033    /**
7034     * @param uri This uri must NOT contain an embedded userId.
7035     * @param userId The userId in which the uri is to be resolved.
7036     */
7037    @Override
7038    public int checkUriPermission(Uri uri, int pid, int uid,
7039            final int modeFlags, int userId, IBinder callerToken) {
7040        enforceNotIsolatedCaller("checkUriPermission");
7041
7042        // Another redirected-binder-call permissions check as in
7043        // {@link checkPermissionWithToken}.
7044        Identity tlsIdentity = sCallerIdentity.get();
7045        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7046            uid = tlsIdentity.uid;
7047            pid = tlsIdentity.pid;
7048        }
7049
7050        // Our own process gets to do everything.
7051        if (pid == MY_PID) {
7052            return PackageManager.PERMISSION_GRANTED;
7053        }
7054        synchronized (this) {
7055            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7056                    ? PackageManager.PERMISSION_GRANTED
7057                    : PackageManager.PERMISSION_DENIED;
7058        }
7059    }
7060
7061    /**
7062     * Check if the targetPkg can be granted permission to access uri by
7063     * the callingUid using the given modeFlags.  Throws a security exception
7064     * if callingUid is not allowed to do this.  Returns the uid of the target
7065     * if the URI permission grant should be performed; returns -1 if it is not
7066     * needed (for example targetPkg already has permission to access the URI).
7067     * If you already know the uid of the target, you can supply it in
7068     * lastTargetUid else set that to -1.
7069     */
7070    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7071            final int modeFlags, int lastTargetUid) {
7072        if (!Intent.isAccessUriMode(modeFlags)) {
7073            return -1;
7074        }
7075
7076        if (targetPkg != null) {
7077            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7078                    "Checking grant " + targetPkg + " permission to " + grantUri);
7079        }
7080
7081        final IPackageManager pm = AppGlobals.getPackageManager();
7082
7083        // If this is not a content: uri, we can't do anything with it.
7084        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7085            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7086                    "Can't grant URI permission for non-content URI: " + grantUri);
7087            return -1;
7088        }
7089
7090        final String authority = grantUri.uri.getAuthority();
7091        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7092        if (pi == null) {
7093            Slog.w(TAG, "No content provider found for permission check: " +
7094                    grantUri.uri.toSafeString());
7095            return -1;
7096        }
7097
7098        int targetUid = lastTargetUid;
7099        if (targetUid < 0 && targetPkg != null) {
7100            try {
7101                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7102                if (targetUid < 0) {
7103                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7104                            "Can't grant URI permission no uid for: " + targetPkg);
7105                    return -1;
7106                }
7107            } catch (RemoteException ex) {
7108                return -1;
7109            }
7110        }
7111
7112        if (targetUid >= 0) {
7113            // First...  does the target actually need this permission?
7114            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7115                // No need to grant the target this permission.
7116                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7117                        "Target " + targetPkg + " already has full permission to " + grantUri);
7118                return -1;
7119            }
7120        } else {
7121            // First...  there is no target package, so can anyone access it?
7122            boolean allowed = pi.exported;
7123            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7124                if (pi.readPermission != null) {
7125                    allowed = false;
7126                }
7127            }
7128            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7129                if (pi.writePermission != null) {
7130                    allowed = false;
7131                }
7132            }
7133            if (allowed) {
7134                return -1;
7135            }
7136        }
7137
7138        /* There is a special cross user grant if:
7139         * - The target is on another user.
7140         * - Apps on the current user can access the uri without any uid permissions.
7141         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7142         * grant uri permissions.
7143         */
7144        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7145                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7146                modeFlags, false /*without considering the uid permissions*/);
7147
7148        // Second...  is the provider allowing granting of URI permissions?
7149        if (!specialCrossUserGrant) {
7150            if (!pi.grantUriPermissions) {
7151                throw new SecurityException("Provider " + pi.packageName
7152                        + "/" + pi.name
7153                        + " does not allow granting of Uri permissions (uri "
7154                        + grantUri + ")");
7155            }
7156            if (pi.uriPermissionPatterns != null) {
7157                final int N = pi.uriPermissionPatterns.length;
7158                boolean allowed = false;
7159                for (int i=0; i<N; i++) {
7160                    if (pi.uriPermissionPatterns[i] != null
7161                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7162                        allowed = true;
7163                        break;
7164                    }
7165                }
7166                if (!allowed) {
7167                    throw new SecurityException("Provider " + pi.packageName
7168                            + "/" + pi.name
7169                            + " does not allow granting of permission to path of Uri "
7170                            + grantUri);
7171                }
7172            }
7173        }
7174
7175        // Third...  does the caller itself have permission to access
7176        // this uri?
7177        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7178            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7179                // Require they hold a strong enough Uri permission
7180                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7181                    throw new SecurityException("Uid " + callingUid
7182                            + " does not have permission to uri " + grantUri);
7183                }
7184            }
7185        }
7186        return targetUid;
7187    }
7188
7189    /**
7190     * @param uri This uri must NOT contain an embedded userId.
7191     * @param userId The userId in which the uri is to be resolved.
7192     */
7193    @Override
7194    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7195            final int modeFlags, int userId) {
7196        enforceNotIsolatedCaller("checkGrantUriPermission");
7197        synchronized(this) {
7198            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7199                    new GrantUri(userId, uri, false), modeFlags, -1);
7200        }
7201    }
7202
7203    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7204            final int modeFlags, UriPermissionOwner owner) {
7205        if (!Intent.isAccessUriMode(modeFlags)) {
7206            return;
7207        }
7208
7209        // So here we are: the caller has the assumed permission
7210        // to the uri, and the target doesn't.  Let's now give this to
7211        // the target.
7212
7213        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7214                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7215
7216        final String authority = grantUri.uri.getAuthority();
7217        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7218        if (pi == null) {
7219            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7220            return;
7221        }
7222
7223        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7224            grantUri.prefix = true;
7225        }
7226        final UriPermission perm = findOrCreateUriPermissionLocked(
7227                pi.packageName, targetPkg, targetUid, grantUri);
7228        perm.grantModes(modeFlags, owner);
7229    }
7230
7231    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7232            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7233        if (targetPkg == null) {
7234            throw new NullPointerException("targetPkg");
7235        }
7236        int targetUid;
7237        final IPackageManager pm = AppGlobals.getPackageManager();
7238        try {
7239            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7240        } catch (RemoteException ex) {
7241            return;
7242        }
7243
7244        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7245                targetUid);
7246        if (targetUid < 0) {
7247            return;
7248        }
7249
7250        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7251                owner);
7252    }
7253
7254    static class NeededUriGrants extends ArrayList<GrantUri> {
7255        final String targetPkg;
7256        final int targetUid;
7257        final int flags;
7258
7259        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7260            this.targetPkg = targetPkg;
7261            this.targetUid = targetUid;
7262            this.flags = flags;
7263        }
7264    }
7265
7266    /**
7267     * Like checkGrantUriPermissionLocked, but takes an Intent.
7268     */
7269    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7270            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7271        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7272                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7273                + " clip=" + (intent != null ? intent.getClipData() : null)
7274                + " from " + intent + "; flags=0x"
7275                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7276
7277        if (targetPkg == null) {
7278            throw new NullPointerException("targetPkg");
7279        }
7280
7281        if (intent == null) {
7282            return null;
7283        }
7284        Uri data = intent.getData();
7285        ClipData clip = intent.getClipData();
7286        if (data == null && clip == null) {
7287            return null;
7288        }
7289        // Default userId for uris in the intent (if they don't specify it themselves)
7290        int contentUserHint = intent.getContentUserHint();
7291        if (contentUserHint == UserHandle.USER_CURRENT) {
7292            contentUserHint = UserHandle.getUserId(callingUid);
7293        }
7294        final IPackageManager pm = AppGlobals.getPackageManager();
7295        int targetUid;
7296        if (needed != null) {
7297            targetUid = needed.targetUid;
7298        } else {
7299            try {
7300                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7301            } catch (RemoteException ex) {
7302                return null;
7303            }
7304            if (targetUid < 0) {
7305                if (DEBUG_URI_PERMISSION) {
7306                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7307                            + " on user " + targetUserId);
7308                }
7309                return null;
7310            }
7311        }
7312        if (data != null) {
7313            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7314            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7315                    targetUid);
7316            if (targetUid > 0) {
7317                if (needed == null) {
7318                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7319                }
7320                needed.add(grantUri);
7321            }
7322        }
7323        if (clip != null) {
7324            for (int i=0; i<clip.getItemCount(); i++) {
7325                Uri uri = clip.getItemAt(i).getUri();
7326                if (uri != null) {
7327                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7328                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7329                            targetUid);
7330                    if (targetUid > 0) {
7331                        if (needed == null) {
7332                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7333                        }
7334                        needed.add(grantUri);
7335                    }
7336                } else {
7337                    Intent clipIntent = clip.getItemAt(i).getIntent();
7338                    if (clipIntent != null) {
7339                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7340                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7341                        if (newNeeded != null) {
7342                            needed = newNeeded;
7343                        }
7344                    }
7345                }
7346            }
7347        }
7348
7349        return needed;
7350    }
7351
7352    /**
7353     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7354     */
7355    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7356            UriPermissionOwner owner) {
7357        if (needed != null) {
7358            for (int i=0; i<needed.size(); i++) {
7359                GrantUri grantUri = needed.get(i);
7360                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7361                        grantUri, needed.flags, owner);
7362            }
7363        }
7364    }
7365
7366    void grantUriPermissionFromIntentLocked(int callingUid,
7367            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7368        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7369                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7370        if (needed == null) {
7371            return;
7372        }
7373
7374        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7375    }
7376
7377    /**
7378     * @param uri This uri must NOT contain an embedded userId.
7379     * @param userId The userId in which the uri is to be resolved.
7380     */
7381    @Override
7382    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7383            final int modeFlags, int userId) {
7384        enforceNotIsolatedCaller("grantUriPermission");
7385        GrantUri grantUri = new GrantUri(userId, uri, false);
7386        synchronized(this) {
7387            final ProcessRecord r = getRecordForAppLocked(caller);
7388            if (r == null) {
7389                throw new SecurityException("Unable to find app for caller "
7390                        + caller
7391                        + " when granting permission to uri " + grantUri);
7392            }
7393            if (targetPkg == null) {
7394                throw new IllegalArgumentException("null target");
7395            }
7396            if (grantUri == null) {
7397                throw new IllegalArgumentException("null uri");
7398            }
7399
7400            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7401                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7402                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7403                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7404
7405            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7406                    UserHandle.getUserId(r.uid));
7407        }
7408    }
7409
7410    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7411        if (perm.modeFlags == 0) {
7412            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7413                    perm.targetUid);
7414            if (perms != null) {
7415                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7416                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7417
7418                perms.remove(perm.uri);
7419                if (perms.isEmpty()) {
7420                    mGrantedUriPermissions.remove(perm.targetUid);
7421                }
7422            }
7423        }
7424    }
7425
7426    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7427        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7428
7429        final IPackageManager pm = AppGlobals.getPackageManager();
7430        final String authority = grantUri.uri.getAuthority();
7431        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7432        if (pi == null) {
7433            Slog.w(TAG, "No content provider found for permission revoke: "
7434                    + grantUri.toSafeString());
7435            return;
7436        }
7437
7438        // Does the caller have this permission on the URI?
7439        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7440            // If they don't have direct access to the URI, then revoke any
7441            // ownerless URI permissions that have been granted to them.
7442            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7443            if (perms != null) {
7444                boolean persistChanged = false;
7445                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7446                    final UriPermission perm = it.next();
7447                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7448                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7449                        if (DEBUG_URI_PERMISSION)
7450                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7451                                    " permission to " + perm.uri);
7452                        persistChanged |= perm.revokeModes(
7453                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7454                        if (perm.modeFlags == 0) {
7455                            it.remove();
7456                        }
7457                    }
7458                }
7459                if (perms.isEmpty()) {
7460                    mGrantedUriPermissions.remove(callingUid);
7461                }
7462                if (persistChanged) {
7463                    schedulePersistUriGrants();
7464                }
7465            }
7466            return;
7467        }
7468
7469        boolean persistChanged = false;
7470
7471        // Go through all of the permissions and remove any that match.
7472        int N = mGrantedUriPermissions.size();
7473        for (int i = 0; i < N; i++) {
7474            final int targetUid = mGrantedUriPermissions.keyAt(i);
7475            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7476
7477            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7478                final UriPermission perm = it.next();
7479                if (perm.uri.sourceUserId == grantUri.sourceUserId
7480                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7481                    if (DEBUG_URI_PERMISSION)
7482                        Slog.v(TAG,
7483                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7484                    persistChanged |= perm.revokeModes(
7485                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7486                    if (perm.modeFlags == 0) {
7487                        it.remove();
7488                    }
7489                }
7490            }
7491
7492            if (perms.isEmpty()) {
7493                mGrantedUriPermissions.remove(targetUid);
7494                N--;
7495                i--;
7496            }
7497        }
7498
7499        if (persistChanged) {
7500            schedulePersistUriGrants();
7501        }
7502    }
7503
7504    /**
7505     * @param uri This uri must NOT contain an embedded userId.
7506     * @param userId The userId in which the uri is to be resolved.
7507     */
7508    @Override
7509    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7510            int userId) {
7511        enforceNotIsolatedCaller("revokeUriPermission");
7512        synchronized(this) {
7513            final ProcessRecord r = getRecordForAppLocked(caller);
7514            if (r == null) {
7515                throw new SecurityException("Unable to find app for caller "
7516                        + caller
7517                        + " when revoking permission to uri " + uri);
7518            }
7519            if (uri == null) {
7520                Slog.w(TAG, "revokeUriPermission: null uri");
7521                return;
7522            }
7523
7524            if (!Intent.isAccessUriMode(modeFlags)) {
7525                return;
7526            }
7527
7528            final IPackageManager pm = AppGlobals.getPackageManager();
7529            final String authority = uri.getAuthority();
7530            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7531            if (pi == null) {
7532                Slog.w(TAG, "No content provider found for permission revoke: "
7533                        + uri.toSafeString());
7534                return;
7535            }
7536
7537            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7538        }
7539    }
7540
7541    /**
7542     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7543     * given package.
7544     *
7545     * @param packageName Package name to match, or {@code null} to apply to all
7546     *            packages.
7547     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7548     *            to all users.
7549     * @param persistable If persistable grants should be removed.
7550     */
7551    private void removeUriPermissionsForPackageLocked(
7552            String packageName, int userHandle, boolean persistable) {
7553        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7554            throw new IllegalArgumentException("Must narrow by either package or user");
7555        }
7556
7557        boolean persistChanged = false;
7558
7559        int N = mGrantedUriPermissions.size();
7560        for (int i = 0; i < N; i++) {
7561            final int targetUid = mGrantedUriPermissions.keyAt(i);
7562            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7563
7564            // Only inspect grants matching user
7565            if (userHandle == UserHandle.USER_ALL
7566                    || userHandle == UserHandle.getUserId(targetUid)) {
7567                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7568                    final UriPermission perm = it.next();
7569
7570                    // Only inspect grants matching package
7571                    if (packageName == null || perm.sourcePkg.equals(packageName)
7572                            || perm.targetPkg.equals(packageName)) {
7573                        persistChanged |= perm.revokeModes(persistable
7574                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7575
7576                        // Only remove when no modes remain; any persisted grants
7577                        // will keep this alive.
7578                        if (perm.modeFlags == 0) {
7579                            it.remove();
7580                        }
7581                    }
7582                }
7583
7584                if (perms.isEmpty()) {
7585                    mGrantedUriPermissions.remove(targetUid);
7586                    N--;
7587                    i--;
7588                }
7589            }
7590        }
7591
7592        if (persistChanged) {
7593            schedulePersistUriGrants();
7594        }
7595    }
7596
7597    @Override
7598    public IBinder newUriPermissionOwner(String name) {
7599        enforceNotIsolatedCaller("newUriPermissionOwner");
7600        synchronized(this) {
7601            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7602            return owner.getExternalTokenLocked();
7603        }
7604    }
7605
7606    /**
7607     * @param uri This uri must NOT contain an embedded userId.
7608     * @param sourceUserId The userId in which the uri is to be resolved.
7609     * @param targetUserId The userId of the app that receives the grant.
7610     */
7611    @Override
7612    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7613            final int modeFlags, int sourceUserId, int targetUserId) {
7614        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7615                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7616        synchronized(this) {
7617            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7618            if (owner == null) {
7619                throw new IllegalArgumentException("Unknown owner: " + token);
7620            }
7621            if (fromUid != Binder.getCallingUid()) {
7622                if (Binder.getCallingUid() != Process.myUid()) {
7623                    // Only system code can grant URI permissions on behalf
7624                    // of other users.
7625                    throw new SecurityException("nice try");
7626                }
7627            }
7628            if (targetPkg == null) {
7629                throw new IllegalArgumentException("null target");
7630            }
7631            if (uri == null) {
7632                throw new IllegalArgumentException("null uri");
7633            }
7634
7635            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7636                    modeFlags, owner, targetUserId);
7637        }
7638    }
7639
7640    /**
7641     * @param uri This uri must NOT contain an embedded userId.
7642     * @param userId The userId in which the uri is to be resolved.
7643     */
7644    @Override
7645    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7646        synchronized(this) {
7647            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7648            if (owner == null) {
7649                throw new IllegalArgumentException("Unknown owner: " + token);
7650            }
7651
7652            if (uri == null) {
7653                owner.removeUriPermissionsLocked(mode);
7654            } else {
7655                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7656            }
7657        }
7658    }
7659
7660    private void schedulePersistUriGrants() {
7661        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7662            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7663                    10 * DateUtils.SECOND_IN_MILLIS);
7664        }
7665    }
7666
7667    private void writeGrantedUriPermissions() {
7668        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7669
7670        // Snapshot permissions so we can persist without lock
7671        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7672        synchronized (this) {
7673            final int size = mGrantedUriPermissions.size();
7674            for (int i = 0; i < size; i++) {
7675                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7676                for (UriPermission perm : perms.values()) {
7677                    if (perm.persistedModeFlags != 0) {
7678                        persist.add(perm.snapshot());
7679                    }
7680                }
7681            }
7682        }
7683
7684        FileOutputStream fos = null;
7685        try {
7686            fos = mGrantFile.startWrite();
7687
7688            XmlSerializer out = new FastXmlSerializer();
7689            out.setOutput(fos, "utf-8");
7690            out.startDocument(null, true);
7691            out.startTag(null, TAG_URI_GRANTS);
7692            for (UriPermission.Snapshot perm : persist) {
7693                out.startTag(null, TAG_URI_GRANT);
7694                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7695                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7696                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7697                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7698                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7699                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7700                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7701                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7702                out.endTag(null, TAG_URI_GRANT);
7703            }
7704            out.endTag(null, TAG_URI_GRANTS);
7705            out.endDocument();
7706
7707            mGrantFile.finishWrite(fos);
7708        } catch (IOException e) {
7709            if (fos != null) {
7710                mGrantFile.failWrite(fos);
7711            }
7712        }
7713    }
7714
7715    private void readGrantedUriPermissionsLocked() {
7716        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7717
7718        final long now = System.currentTimeMillis();
7719
7720        FileInputStream fis = null;
7721        try {
7722            fis = mGrantFile.openRead();
7723            final XmlPullParser in = Xml.newPullParser();
7724            in.setInput(fis, null);
7725
7726            int type;
7727            while ((type = in.next()) != END_DOCUMENT) {
7728                final String tag = in.getName();
7729                if (type == START_TAG) {
7730                    if (TAG_URI_GRANT.equals(tag)) {
7731                        final int sourceUserId;
7732                        final int targetUserId;
7733                        final int userHandle = readIntAttribute(in,
7734                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7735                        if (userHandle != UserHandle.USER_NULL) {
7736                            // For backwards compatibility.
7737                            sourceUserId = userHandle;
7738                            targetUserId = userHandle;
7739                        } else {
7740                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7741                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7742                        }
7743                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7744                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7745                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7746                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7747                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7748                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7749
7750                        // Sanity check that provider still belongs to source package
7751                        final ProviderInfo pi = getProviderInfoLocked(
7752                                uri.getAuthority(), sourceUserId);
7753                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7754                            int targetUid = -1;
7755                            try {
7756                                targetUid = AppGlobals.getPackageManager()
7757                                        .getPackageUid(targetPkg, targetUserId);
7758                            } catch (RemoteException e) {
7759                            }
7760                            if (targetUid != -1) {
7761                                final UriPermission perm = findOrCreateUriPermissionLocked(
7762                                        sourcePkg, targetPkg, targetUid,
7763                                        new GrantUri(sourceUserId, uri, prefix));
7764                                perm.initPersistedModes(modeFlags, createdTime);
7765                            }
7766                        } else {
7767                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7768                                    + " but instead found " + pi);
7769                        }
7770                    }
7771                }
7772            }
7773        } catch (FileNotFoundException e) {
7774            // Missing grants is okay
7775        } catch (IOException e) {
7776            Slog.wtf(TAG, "Failed reading Uri grants", e);
7777        } catch (XmlPullParserException e) {
7778            Slog.wtf(TAG, "Failed reading Uri grants", e);
7779        } finally {
7780            IoUtils.closeQuietly(fis);
7781        }
7782    }
7783
7784    /**
7785     * @param uri This uri must NOT contain an embedded userId.
7786     * @param userId The userId in which the uri is to be resolved.
7787     */
7788    @Override
7789    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7790        enforceNotIsolatedCaller("takePersistableUriPermission");
7791
7792        Preconditions.checkFlagsArgument(modeFlags,
7793                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7794
7795        synchronized (this) {
7796            final int callingUid = Binder.getCallingUid();
7797            boolean persistChanged = false;
7798            GrantUri grantUri = new GrantUri(userId, uri, false);
7799
7800            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7801                    new GrantUri(userId, uri, false));
7802            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7803                    new GrantUri(userId, uri, true));
7804
7805            final boolean exactValid = (exactPerm != null)
7806                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7807            final boolean prefixValid = (prefixPerm != null)
7808                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7809
7810            if (!(exactValid || prefixValid)) {
7811                throw new SecurityException("No persistable permission grants found for UID "
7812                        + callingUid + " and Uri " + grantUri.toSafeString());
7813            }
7814
7815            if (exactValid) {
7816                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7817            }
7818            if (prefixValid) {
7819                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7820            }
7821
7822            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7823
7824            if (persistChanged) {
7825                schedulePersistUriGrants();
7826            }
7827        }
7828    }
7829
7830    /**
7831     * @param uri This uri must NOT contain an embedded userId.
7832     * @param userId The userId in which the uri is to be resolved.
7833     */
7834    @Override
7835    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7836        enforceNotIsolatedCaller("releasePersistableUriPermission");
7837
7838        Preconditions.checkFlagsArgument(modeFlags,
7839                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7840
7841        synchronized (this) {
7842            final int callingUid = Binder.getCallingUid();
7843            boolean persistChanged = false;
7844
7845            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7846                    new GrantUri(userId, uri, false));
7847            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7848                    new GrantUri(userId, uri, true));
7849            if (exactPerm == null && prefixPerm == null) {
7850                throw new SecurityException("No permission grants found for UID " + callingUid
7851                        + " and Uri " + uri.toSafeString());
7852            }
7853
7854            if (exactPerm != null) {
7855                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7856                removeUriPermissionIfNeededLocked(exactPerm);
7857            }
7858            if (prefixPerm != null) {
7859                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7860                removeUriPermissionIfNeededLocked(prefixPerm);
7861            }
7862
7863            if (persistChanged) {
7864                schedulePersistUriGrants();
7865            }
7866        }
7867    }
7868
7869    /**
7870     * Prune any older {@link UriPermission} for the given UID until outstanding
7871     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7872     *
7873     * @return if any mutations occured that require persisting.
7874     */
7875    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7876        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7877        if (perms == null) return false;
7878        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7879
7880        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7881        for (UriPermission perm : perms.values()) {
7882            if (perm.persistedModeFlags != 0) {
7883                persisted.add(perm);
7884            }
7885        }
7886
7887        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7888        if (trimCount <= 0) return false;
7889
7890        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7891        for (int i = 0; i < trimCount; i++) {
7892            final UriPermission perm = persisted.get(i);
7893
7894            if (DEBUG_URI_PERMISSION) {
7895                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7896            }
7897
7898            perm.releasePersistableModes(~0);
7899            removeUriPermissionIfNeededLocked(perm);
7900        }
7901
7902        return true;
7903    }
7904
7905    @Override
7906    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7907            String packageName, boolean incoming) {
7908        enforceNotIsolatedCaller("getPersistedUriPermissions");
7909        Preconditions.checkNotNull(packageName, "packageName");
7910
7911        final int callingUid = Binder.getCallingUid();
7912        final IPackageManager pm = AppGlobals.getPackageManager();
7913        try {
7914            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7915            if (packageUid != callingUid) {
7916                throw new SecurityException(
7917                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7918            }
7919        } catch (RemoteException e) {
7920            throw new SecurityException("Failed to verify package name ownership");
7921        }
7922
7923        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7924        synchronized (this) {
7925            if (incoming) {
7926                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7927                        callingUid);
7928                if (perms == null) {
7929                    Slog.w(TAG, "No permission grants found for " + packageName);
7930                } else {
7931                    for (UriPermission perm : perms.values()) {
7932                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7933                            result.add(perm.buildPersistedPublicApiObject());
7934                        }
7935                    }
7936                }
7937            } else {
7938                final int size = mGrantedUriPermissions.size();
7939                for (int i = 0; i < size; i++) {
7940                    final ArrayMap<GrantUri, UriPermission> perms =
7941                            mGrantedUriPermissions.valueAt(i);
7942                    for (UriPermission perm : perms.values()) {
7943                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7944                            result.add(perm.buildPersistedPublicApiObject());
7945                        }
7946                    }
7947                }
7948            }
7949        }
7950        return new ParceledListSlice<android.content.UriPermission>(result);
7951    }
7952
7953    @Override
7954    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7955        synchronized (this) {
7956            ProcessRecord app =
7957                who != null ? getRecordForAppLocked(who) : null;
7958            if (app == null) return;
7959
7960            Message msg = Message.obtain();
7961            msg.what = WAIT_FOR_DEBUGGER_MSG;
7962            msg.obj = app;
7963            msg.arg1 = waiting ? 1 : 0;
7964            mHandler.sendMessage(msg);
7965        }
7966    }
7967
7968    @Override
7969    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7970        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7971        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7972        outInfo.availMem = Process.getFreeMemory();
7973        outInfo.totalMem = Process.getTotalMemory();
7974        outInfo.threshold = homeAppMem;
7975        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7976        outInfo.hiddenAppThreshold = cachedAppMem;
7977        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7978                ProcessList.SERVICE_ADJ);
7979        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7980                ProcessList.VISIBLE_APP_ADJ);
7981        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7982                ProcessList.FOREGROUND_APP_ADJ);
7983    }
7984
7985    // =========================================================
7986    // TASK MANAGEMENT
7987    // =========================================================
7988
7989    @Override
7990    public List<IAppTask> getAppTasks(String callingPackage) {
7991        int callingUid = Binder.getCallingUid();
7992        long ident = Binder.clearCallingIdentity();
7993
7994        synchronized(this) {
7995            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7996            try {
7997                if (localLOGV) Slog.v(TAG, "getAppTasks");
7998
7999                final int N = mRecentTasks.size();
8000                for (int i = 0; i < N; i++) {
8001                    TaskRecord tr = mRecentTasks.get(i);
8002                    // Skip tasks that do not match the caller.  We don't need to verify
8003                    // callingPackage, because we are also limiting to callingUid and know
8004                    // that will limit to the correct security sandbox.
8005                    if (tr.effectiveUid != callingUid) {
8006                        continue;
8007                    }
8008                    Intent intent = tr.getBaseIntent();
8009                    if (intent == null ||
8010                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8011                        continue;
8012                    }
8013                    ActivityManager.RecentTaskInfo taskInfo =
8014                            createRecentTaskInfoFromTaskRecord(tr);
8015                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8016                    list.add(taskImpl);
8017                }
8018            } finally {
8019                Binder.restoreCallingIdentity(ident);
8020            }
8021            return list;
8022        }
8023    }
8024
8025    @Override
8026    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8027        final int callingUid = Binder.getCallingUid();
8028        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8029
8030        synchronized(this) {
8031            if (localLOGV) Slog.v(
8032                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8033
8034            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8035                    callingUid);
8036
8037            // TODO: Improve with MRU list from all ActivityStacks.
8038            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8039        }
8040
8041        return list;
8042    }
8043
8044    /**
8045     * Creates a new RecentTaskInfo from a TaskRecord.
8046     */
8047    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8048        // Update the task description to reflect any changes in the task stack
8049        tr.updateTaskDescription();
8050
8051        // Compose the recent task info
8052        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8053        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8054        rti.persistentId = tr.taskId;
8055        rti.baseIntent = new Intent(tr.getBaseIntent());
8056        rti.origActivity = tr.origActivity;
8057        rti.description = tr.lastDescription;
8058        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8059        rti.userId = tr.userId;
8060        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8061        rti.firstActiveTime = tr.firstActiveTime;
8062        rti.lastActiveTime = tr.lastActiveTime;
8063        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8064        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8065        return rti;
8066    }
8067
8068    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8069        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8070                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8071        if (!allowed) {
8072            if (checkPermission(android.Manifest.permission.GET_TASKS,
8073                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8074                // Temporary compatibility: some existing apps on the system image may
8075                // still be requesting the old permission and not switched to the new
8076                // one; if so, we'll still allow them full access.  This means we need
8077                // to see if they are holding the old permission and are a system app.
8078                try {
8079                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8080                        allowed = true;
8081                        Slog.w(TAG, caller + ": caller " + callingUid
8082                                + " is using old GET_TASKS but privileged; allowing");
8083                    }
8084                } catch (RemoteException e) {
8085                }
8086            }
8087        }
8088        if (!allowed) {
8089            Slog.w(TAG, caller + ": caller " + callingUid
8090                    + " does not hold GET_TASKS; limiting output");
8091        }
8092        return allowed;
8093    }
8094
8095    @Override
8096    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8097        final int callingUid = Binder.getCallingUid();
8098        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8099                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8100
8101        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8102        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8103        synchronized (this) {
8104            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8105                    callingUid);
8106            final boolean detailed = checkCallingPermission(
8107                    android.Manifest.permission.GET_DETAILED_TASKS)
8108                    == PackageManager.PERMISSION_GRANTED;
8109
8110            final int N = mRecentTasks.size();
8111            ArrayList<ActivityManager.RecentTaskInfo> res
8112                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8113                            maxNum < N ? maxNum : N);
8114
8115            final Set<Integer> includedUsers;
8116            if (includeProfiles) {
8117                includedUsers = getProfileIdsLocked(userId);
8118            } else {
8119                includedUsers = new HashSet<Integer>();
8120            }
8121            includedUsers.add(Integer.valueOf(userId));
8122
8123            for (int i=0; i<N && maxNum > 0; i++) {
8124                TaskRecord tr = mRecentTasks.get(i);
8125                // Only add calling user or related users recent tasks
8126                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8127                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8128                    continue;
8129                }
8130
8131                // Return the entry if desired by the caller.  We always return
8132                // the first entry, because callers always expect this to be the
8133                // foreground app.  We may filter others if the caller has
8134                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8135                // we should exclude the entry.
8136
8137                if (i == 0
8138                        || withExcluded
8139                        || (tr.intent == null)
8140                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8141                                == 0)) {
8142                    if (!allowed) {
8143                        // If the caller doesn't have the GET_TASKS permission, then only
8144                        // allow them to see a small subset of tasks -- their own and home.
8145                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8146                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8147                            continue;
8148                        }
8149                    }
8150                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8151                        if (tr.stack != null && tr.stack.isHomeStack()) {
8152                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8153                            continue;
8154                        }
8155                    }
8156                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8157                        // Don't include auto remove tasks that are finished or finishing.
8158                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8159                                + tr);
8160                        continue;
8161                    }
8162                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8163                            && !tr.isAvailable) {
8164                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8165                        continue;
8166                    }
8167
8168                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8169                    if (!detailed) {
8170                        rti.baseIntent.replaceExtras((Bundle)null);
8171                    }
8172
8173                    res.add(rti);
8174                    maxNum--;
8175                }
8176            }
8177            return res;
8178        }
8179    }
8180
8181    private TaskRecord taskForIdLocked(int id) {
8182        final TaskRecord task = recentTaskForIdLocked(id);
8183        if (task != null) {
8184            return task;
8185        }
8186
8187        // Don't give up. Sometimes it just hasn't made it to recents yet.
8188        return mStackSupervisor.anyTaskForIdLocked(id);
8189    }
8190
8191    private TaskRecord recentTaskForIdLocked(int id) {
8192        final int N = mRecentTasks.size();
8193            for (int i=0; i<N; i++) {
8194                TaskRecord tr = mRecentTasks.get(i);
8195                if (tr.taskId == id) {
8196                    return tr;
8197                }
8198            }
8199            return null;
8200    }
8201
8202    @Override
8203    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8204        synchronized (this) {
8205            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8206                    "getTaskThumbnail()");
8207            TaskRecord tr = recentTaskForIdLocked(id);
8208            if (tr != null) {
8209                return tr.getTaskThumbnailLocked();
8210            }
8211        }
8212        return null;
8213    }
8214
8215    @Override
8216    public int addAppTask(IBinder activityToken, Intent intent,
8217            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8218        final int callingUid = Binder.getCallingUid();
8219        final long callingIdent = Binder.clearCallingIdentity();
8220
8221        try {
8222            synchronized (this) {
8223                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8224                if (r == null) {
8225                    throw new IllegalArgumentException("Activity does not exist; token="
8226                            + activityToken);
8227                }
8228                ComponentName comp = intent.getComponent();
8229                if (comp == null) {
8230                    throw new IllegalArgumentException("Intent " + intent
8231                            + " must specify explicit component");
8232                }
8233                if (thumbnail.getWidth() != mThumbnailWidth
8234                        || thumbnail.getHeight() != mThumbnailHeight) {
8235                    throw new IllegalArgumentException("Bad thumbnail size: got "
8236                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8237                            + mThumbnailWidth + "x" + mThumbnailHeight);
8238                }
8239                if (intent.getSelector() != null) {
8240                    intent.setSelector(null);
8241                }
8242                if (intent.getSourceBounds() != null) {
8243                    intent.setSourceBounds(null);
8244                }
8245                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8246                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8247                        // The caller has added this as an auto-remove task...  that makes no
8248                        // sense, so turn off auto-remove.
8249                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8250                    }
8251                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8252                    // Must be a new task.
8253                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8254                }
8255                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8256                    mLastAddedTaskActivity = null;
8257                }
8258                ActivityInfo ainfo = mLastAddedTaskActivity;
8259                if (ainfo == null) {
8260                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8261                            comp, 0, UserHandle.getUserId(callingUid));
8262                    if (ainfo.applicationInfo.uid != callingUid) {
8263                        throw new SecurityException(
8264                                "Can't add task for another application: target uid="
8265                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8266                    }
8267                }
8268
8269                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8270                        intent, description);
8271
8272                int trimIdx = trimRecentsForTaskLocked(task, false);
8273                if (trimIdx >= 0) {
8274                    // If this would have caused a trim, then we'll abort because that
8275                    // means it would be added at the end of the list but then just removed.
8276                    return INVALID_TASK_ID;
8277                }
8278
8279                final int N = mRecentTasks.size();
8280                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8281                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8282                    tr.removedFromRecents();
8283                }
8284
8285                task.inRecents = true;
8286                mRecentTasks.add(task);
8287                r.task.stack.addTask(task, false, false);
8288
8289                task.setLastThumbnail(thumbnail);
8290                task.freeLastThumbnail();
8291
8292                return task.taskId;
8293            }
8294        } finally {
8295            Binder.restoreCallingIdentity(callingIdent);
8296        }
8297    }
8298
8299    @Override
8300    public Point getAppTaskThumbnailSize() {
8301        synchronized (this) {
8302            return new Point(mThumbnailWidth,  mThumbnailHeight);
8303        }
8304    }
8305
8306    @Override
8307    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8308        synchronized (this) {
8309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8310            if (r != null) {
8311                r.setTaskDescription(td);
8312                r.task.updateTaskDescription();
8313            }
8314        }
8315    }
8316
8317    @Override
8318    public Bitmap getTaskDescriptionIcon(String filename) {
8319        if (!FileUtils.isValidExtFilename(filename)
8320                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8321            throw new IllegalArgumentException("Bad filename: " + filename);
8322        }
8323        return mTaskPersister.getTaskDescriptionIcon(filename);
8324    }
8325
8326    @Override
8327    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8328            throws RemoteException {
8329        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8330                opts.getCustomInPlaceResId() == 0) {
8331            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8332                    "with valid animation");
8333        }
8334        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8335        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8336                opts.getCustomInPlaceResId());
8337        mWindowManager.executeAppTransition();
8338    }
8339
8340    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8341        mRecentTasks.remove(tr);
8342        tr.removedFromRecents();
8343        ComponentName component = tr.getBaseIntent().getComponent();
8344        if (component == null) {
8345            Slog.w(TAG, "No component for base intent of task: " + tr);
8346            return;
8347        }
8348
8349        if (!killProcess) {
8350            return;
8351        }
8352
8353        // Determine if the process(es) for this task should be killed.
8354        final String pkg = component.getPackageName();
8355        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8356        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8357        for (int i = 0; i < pmap.size(); i++) {
8358
8359            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8360            for (int j = 0; j < uids.size(); j++) {
8361                ProcessRecord proc = uids.valueAt(j);
8362                if (proc.userId != tr.userId) {
8363                    // Don't kill process for a different user.
8364                    continue;
8365                }
8366                if (proc == mHomeProcess) {
8367                    // Don't kill the home process along with tasks from the same package.
8368                    continue;
8369                }
8370                if (!proc.pkgList.containsKey(pkg)) {
8371                    // Don't kill process that is not associated with this task.
8372                    continue;
8373                }
8374
8375                for (int k = 0; k < proc.activities.size(); k++) {
8376                    TaskRecord otherTask = proc.activities.get(k).task;
8377                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8378                        // Don't kill process(es) that has an activity in a different task that is
8379                        // also in recents.
8380                        return;
8381                    }
8382                }
8383
8384                // Add process to kill list.
8385                procsToKill.add(proc);
8386            }
8387        }
8388
8389        // Find any running services associated with this app and stop if needed.
8390        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8391
8392        // Kill the running processes.
8393        for (int i = 0; i < procsToKill.size(); i++) {
8394            ProcessRecord pr = procsToKill.get(i);
8395            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8396                pr.kill("remove task", true);
8397            } else {
8398                pr.waitingToKill = "remove task";
8399            }
8400        }
8401    }
8402
8403    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8404        // Remove all tasks with activities in the specified package from the list of recent tasks
8405        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8406            TaskRecord tr = mRecentTasks.get(i);
8407            if (tr.userId != userId) continue;
8408
8409            ComponentName cn = tr.intent.getComponent();
8410            if (cn != null && cn.getPackageName().equals(packageName)) {
8411                // If the package name matches, remove the task.
8412                removeTaskByIdLocked(tr.taskId, true);
8413            }
8414        }
8415    }
8416
8417    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8418        final IPackageManager pm = AppGlobals.getPackageManager();
8419        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8420
8421        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8422            TaskRecord tr = mRecentTasks.get(i);
8423            if (tr.userId != userId) continue;
8424
8425            ComponentName cn = tr.intent.getComponent();
8426            if (cn != null && cn.getPackageName().equals(packageName)) {
8427                // Skip if component still exists in the package.
8428                if (componentsKnownToExist.contains(cn)) continue;
8429
8430                try {
8431                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8432                    if (info != null) {
8433                        componentsKnownToExist.add(cn);
8434                    } else {
8435                        removeTaskByIdLocked(tr.taskId, false);
8436                    }
8437                } catch (RemoteException e) {
8438                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8439                }
8440            }
8441        }
8442    }
8443
8444    /**
8445     * Removes the task with the specified task id.
8446     *
8447     * @param taskId Identifier of the task to be removed.
8448     * @param killProcess Kill any process associated with the task if possible.
8449     * @return Returns true if the given task was found and removed.
8450     */
8451    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8452        TaskRecord tr = taskForIdLocked(taskId);
8453        if (tr != null) {
8454            tr.removeTaskActivitiesLocked();
8455            cleanUpRemovedTaskLocked(tr, killProcess);
8456            if (tr.isPersistable) {
8457                notifyTaskPersisterLocked(null, true);
8458            }
8459            return true;
8460        }
8461        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8462        return false;
8463    }
8464
8465    @Override
8466    public boolean removeTask(int taskId) {
8467        synchronized (this) {
8468            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8469                    "removeTask()");
8470            long ident = Binder.clearCallingIdentity();
8471            try {
8472                return removeTaskByIdLocked(taskId, true);
8473            } finally {
8474                Binder.restoreCallingIdentity(ident);
8475            }
8476        }
8477    }
8478
8479    /**
8480     * TODO: Add mController hook
8481     */
8482    @Override
8483    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8484        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8485                "moveTaskToFront()");
8486
8487        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8488        synchronized(this) {
8489            moveTaskToFrontLocked(taskId, flags, options);
8490        }
8491    }
8492
8493    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8494        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8495                Binder.getCallingUid(), -1, -1, "Task to front")) {
8496            ActivityOptions.abort(options);
8497            return;
8498        }
8499        final long origId = Binder.clearCallingIdentity();
8500        try {
8501            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8502            if (task == null) {
8503                Slog.d(TAG, "Could not find task for id: "+ taskId);
8504                return;
8505            }
8506            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8507                mStackSupervisor.showLockTaskToast();
8508                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8509                return;
8510            }
8511            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8512            if (prev != null && prev.isRecentsActivity()) {
8513                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8514            }
8515            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8516        } finally {
8517            Binder.restoreCallingIdentity(origId);
8518        }
8519        ActivityOptions.abort(options);
8520    }
8521
8522    @Override
8523    public void moveTaskToBack(int taskId) {
8524        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8525                "moveTaskToBack()");
8526
8527        synchronized(this) {
8528            TaskRecord tr = taskForIdLocked(taskId);
8529            if (tr != null) {
8530                if (tr == mStackSupervisor.mLockTaskModeTask) {
8531                    mStackSupervisor.showLockTaskToast();
8532                    return;
8533                }
8534                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8535                ActivityStack stack = tr.stack;
8536                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8537                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8538                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8539                        return;
8540                    }
8541                }
8542                final long origId = Binder.clearCallingIdentity();
8543                try {
8544                    stack.moveTaskToBackLocked(taskId, null);
8545                } finally {
8546                    Binder.restoreCallingIdentity(origId);
8547                }
8548            }
8549        }
8550    }
8551
8552    /**
8553     * Moves an activity, and all of the other activities within the same task, to the bottom
8554     * of the history stack.  The activity's order within the task is unchanged.
8555     *
8556     * @param token A reference to the activity we wish to move
8557     * @param nonRoot If false then this only works if the activity is the root
8558     *                of a task; if true it will work for any activity in a task.
8559     * @return Returns true if the move completed, false if not.
8560     */
8561    @Override
8562    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8563        enforceNotIsolatedCaller("moveActivityTaskToBack");
8564        synchronized(this) {
8565            final long origId = Binder.clearCallingIdentity();
8566            try {
8567                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8568                if (taskId >= 0) {
8569                    if ((mStackSupervisor.mLockTaskModeTask != null)
8570                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8571                        mStackSupervisor.showLockTaskToast();
8572                        return false;
8573                    }
8574                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8575                }
8576            } finally {
8577                Binder.restoreCallingIdentity(origId);
8578            }
8579        }
8580        return false;
8581    }
8582
8583    @Override
8584    public void moveTaskBackwards(int task) {
8585        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8586                "moveTaskBackwards()");
8587
8588        synchronized(this) {
8589            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8590                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8591                return;
8592            }
8593            final long origId = Binder.clearCallingIdentity();
8594            moveTaskBackwardsLocked(task);
8595            Binder.restoreCallingIdentity(origId);
8596        }
8597    }
8598
8599    private final void moveTaskBackwardsLocked(int task) {
8600        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8601    }
8602
8603    @Override
8604    public IBinder getHomeActivityToken() throws RemoteException {
8605        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8606                "getHomeActivityToken()");
8607        synchronized (this) {
8608            return mStackSupervisor.getHomeActivityToken();
8609        }
8610    }
8611
8612    @Override
8613    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8614            IActivityContainerCallback callback) throws RemoteException {
8615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8616                "createActivityContainer()");
8617        synchronized (this) {
8618            if (parentActivityToken == null) {
8619                throw new IllegalArgumentException("parent token must not be null");
8620            }
8621            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8622            if (r == null) {
8623                return null;
8624            }
8625            if (callback == null) {
8626                throw new IllegalArgumentException("callback must not be null");
8627            }
8628            return mStackSupervisor.createActivityContainer(r, callback);
8629        }
8630    }
8631
8632    @Override
8633    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8634        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8635                "deleteActivityContainer()");
8636        synchronized (this) {
8637            mStackSupervisor.deleteActivityContainer(container);
8638        }
8639    }
8640
8641    @Override
8642    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8643            throws RemoteException {
8644        synchronized (this) {
8645            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8646            if (stack != null) {
8647                return stack.mActivityContainer;
8648            }
8649            return null;
8650        }
8651    }
8652
8653    @Override
8654    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8655        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8656                "moveTaskToStack()");
8657        if (stackId == HOME_STACK_ID) {
8658            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8659                    new RuntimeException("here").fillInStackTrace());
8660        }
8661        synchronized (this) {
8662            long ident = Binder.clearCallingIdentity();
8663            try {
8664                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8665                        + stackId + " toTop=" + toTop);
8666                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8667            } finally {
8668                Binder.restoreCallingIdentity(ident);
8669            }
8670        }
8671    }
8672
8673    @Override
8674    public void resizeStack(int stackBoxId, Rect bounds) {
8675        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8676                "resizeStackBox()");
8677        long ident = Binder.clearCallingIdentity();
8678        try {
8679            mWindowManager.resizeStack(stackBoxId, bounds);
8680        } finally {
8681            Binder.restoreCallingIdentity(ident);
8682        }
8683    }
8684
8685    @Override
8686    public List<StackInfo> getAllStackInfos() {
8687        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8688                "getAllStackInfos()");
8689        long ident = Binder.clearCallingIdentity();
8690        try {
8691            synchronized (this) {
8692                return mStackSupervisor.getAllStackInfosLocked();
8693            }
8694        } finally {
8695            Binder.restoreCallingIdentity(ident);
8696        }
8697    }
8698
8699    @Override
8700    public StackInfo getStackInfo(int stackId) {
8701        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8702                "getStackInfo()");
8703        long ident = Binder.clearCallingIdentity();
8704        try {
8705            synchronized (this) {
8706                return mStackSupervisor.getStackInfoLocked(stackId);
8707            }
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public boolean isInHomeStack(int taskId) {
8715        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8716                "getStackInfo()");
8717        long ident = Binder.clearCallingIdentity();
8718        try {
8719            synchronized (this) {
8720                TaskRecord tr = taskForIdLocked(taskId);
8721                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8722            }
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726    }
8727
8728    @Override
8729    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8730        synchronized(this) {
8731            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8732        }
8733    }
8734
8735    private boolean isLockTaskAuthorized(String pkg) {
8736        final DevicePolicyManager dpm = (DevicePolicyManager)
8737                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8738        try {
8739            int uid = mContext.getPackageManager().getPackageUid(pkg,
8740                    Binder.getCallingUserHandle().getIdentifier());
8741            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8742        } catch (NameNotFoundException e) {
8743            return false;
8744        }
8745    }
8746
8747    void startLockTaskMode(TaskRecord task) {
8748        final String pkg;
8749        synchronized (this) {
8750            pkg = task.intent.getComponent().getPackageName();
8751        }
8752        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8753        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8754            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8755                    StatusBarManagerInternal.class);
8756            if (statusBarManager != null) {
8757                statusBarManager.showScreenPinningRequest();
8758            }
8759            return;
8760        }
8761        long ident = Binder.clearCallingIdentity();
8762        try {
8763            synchronized (this) {
8764                // Since we lost lock on task, make sure it is still there.
8765                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8766                if (task != null) {
8767                    if (!isSystemInitiated
8768                            && ((mStackSupervisor.getFocusedStack() == null)
8769                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8770                        throw new IllegalArgumentException("Invalid task, not in foreground");
8771                    }
8772                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8773                }
8774            }
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public void startLockTaskMode(int taskId) {
8782        final TaskRecord task;
8783        long ident = Binder.clearCallingIdentity();
8784        try {
8785            synchronized (this) {
8786                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8787            }
8788        } finally {
8789            Binder.restoreCallingIdentity(ident);
8790        }
8791        if (task != null) {
8792            startLockTaskMode(task);
8793        }
8794    }
8795
8796    @Override
8797    public void startLockTaskMode(IBinder token) {
8798        final TaskRecord task;
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            synchronized (this) {
8802                final ActivityRecord r = ActivityRecord.forToken(token);
8803                if (r == null) {
8804                    return;
8805                }
8806                task = r.task;
8807            }
8808        } finally {
8809            Binder.restoreCallingIdentity(ident);
8810        }
8811        if (task != null) {
8812            startLockTaskMode(task);
8813        }
8814    }
8815
8816    @Override
8817    public void startLockTaskModeOnCurrent() throws RemoteException {
8818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8819                "startLockTaskModeOnCurrent");
8820        long ident = Binder.clearCallingIdentity();
8821        try {
8822            ActivityRecord r = null;
8823            synchronized (this) {
8824                r = mStackSupervisor.topRunningActivityLocked();
8825            }
8826            startLockTaskMode(r.task);
8827        } finally {
8828            Binder.restoreCallingIdentity(ident);
8829        }
8830    }
8831
8832    @Override
8833    public void stopLockTaskMode() {
8834        // Verify that the user matches the package of the intent for the TaskRecord
8835        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8836        // and stopLockTaskMode.
8837        final int callingUid = Binder.getCallingUid();
8838        if (callingUid != Process.SYSTEM_UID) {
8839            try {
8840                String pkg =
8841                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8842                int uid = mContext.getPackageManager().getPackageUid(pkg,
8843                        Binder.getCallingUserHandle().getIdentifier());
8844                if (uid != callingUid) {
8845                    throw new SecurityException("Invalid uid, expected " + uid);
8846                }
8847            } catch (NameNotFoundException e) {
8848                Log.d(TAG, "stopLockTaskMode " + e);
8849                return;
8850            }
8851        }
8852        long ident = Binder.clearCallingIdentity();
8853        try {
8854            Log.d(TAG, "stopLockTaskMode");
8855            // Stop lock task
8856            synchronized (this) {
8857                mStackSupervisor.setLockTaskModeLocked(null, false);
8858            }
8859        } finally {
8860            Binder.restoreCallingIdentity(ident);
8861        }
8862    }
8863
8864    @Override
8865    public void stopLockTaskModeOnCurrent() throws RemoteException {
8866        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8867                "stopLockTaskModeOnCurrent");
8868        long ident = Binder.clearCallingIdentity();
8869        try {
8870            stopLockTaskMode();
8871        } finally {
8872            Binder.restoreCallingIdentity(ident);
8873        }
8874    }
8875
8876    @Override
8877    public boolean isInLockTaskMode() {
8878        synchronized (this) {
8879            return mStackSupervisor.isInLockTaskMode();
8880        }
8881    }
8882
8883    // =========================================================
8884    // CONTENT PROVIDERS
8885    // =========================================================
8886
8887    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8888        List<ProviderInfo> providers = null;
8889        try {
8890            providers = AppGlobals.getPackageManager().
8891                queryContentProviders(app.processName, app.uid,
8892                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8893        } catch (RemoteException ex) {
8894        }
8895        if (DEBUG_MU)
8896            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8897        int userId = app.userId;
8898        if (providers != null) {
8899            int N = providers.size();
8900            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8901            for (int i=0; i<N; i++) {
8902                ProviderInfo cpi =
8903                    (ProviderInfo)providers.get(i);
8904                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8905                        cpi.name, cpi.flags);
8906                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8907                    // This is a singleton provider, but a user besides the
8908                    // default user is asking to initialize a process it runs
8909                    // in...  well, no, it doesn't actually run in this process,
8910                    // it runs in the process of the default user.  Get rid of it.
8911                    providers.remove(i);
8912                    N--;
8913                    i--;
8914                    continue;
8915                }
8916
8917                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8918                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8919                if (cpr == null) {
8920                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8921                    mProviderMap.putProviderByClass(comp, cpr);
8922                }
8923                if (DEBUG_MU)
8924                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8925                app.pubProviders.put(cpi.name, cpr);
8926                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8927                    // Don't add this if it is a platform component that is marked
8928                    // to run in multiple processes, because this is actually
8929                    // part of the framework so doesn't make sense to track as a
8930                    // separate apk in the process.
8931                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8932                            mProcessStats);
8933                }
8934                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8935            }
8936        }
8937        return providers;
8938    }
8939
8940    /**
8941     * Check if {@link ProcessRecord} has a possible chance at accessing the
8942     * given {@link ProviderInfo}. Final permission checking is always done
8943     * in {@link ContentProvider}.
8944     */
8945    private final String checkContentProviderPermissionLocked(
8946            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8947        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8948        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8949        boolean checkedGrants = false;
8950        if (checkUser) {
8951            // Looking for cross-user grants before enforcing the typical cross-users permissions
8952            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8953            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8954                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8955                    return null;
8956                }
8957                checkedGrants = true;
8958            }
8959            userId = handleIncomingUser(callingPid, callingUid, userId,
8960                    false, ALLOW_NON_FULL,
8961                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8962            if (userId != tmpTargetUserId) {
8963                // When we actually went to determine the final targer user ID, this ended
8964                // up different than our initial check for the authority.  This is because
8965                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8966                // SELF.  So we need to re-check the grants again.
8967                checkedGrants = false;
8968            }
8969        }
8970        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8971                cpi.applicationInfo.uid, cpi.exported)
8972                == PackageManager.PERMISSION_GRANTED) {
8973            return null;
8974        }
8975        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8976                cpi.applicationInfo.uid, cpi.exported)
8977                == PackageManager.PERMISSION_GRANTED) {
8978            return null;
8979        }
8980
8981        PathPermission[] pps = cpi.pathPermissions;
8982        if (pps != null) {
8983            int i = pps.length;
8984            while (i > 0) {
8985                i--;
8986                PathPermission pp = pps[i];
8987                String pprperm = pp.getReadPermission();
8988                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8989                        cpi.applicationInfo.uid, cpi.exported)
8990                        == PackageManager.PERMISSION_GRANTED) {
8991                    return null;
8992                }
8993                String ppwperm = pp.getWritePermission();
8994                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8995                        cpi.applicationInfo.uid, cpi.exported)
8996                        == PackageManager.PERMISSION_GRANTED) {
8997                    return null;
8998                }
8999            }
9000        }
9001        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9002            return null;
9003        }
9004
9005        String msg;
9006        if (!cpi.exported) {
9007            msg = "Permission Denial: opening provider " + cpi.name
9008                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9009                    + ", uid=" + callingUid + ") that is not exported from uid "
9010                    + cpi.applicationInfo.uid;
9011        } else {
9012            msg = "Permission Denial: opening provider " + cpi.name
9013                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9014                    + ", uid=" + callingUid + ") requires "
9015                    + cpi.readPermission + " or " + cpi.writePermission;
9016        }
9017        Slog.w(TAG, msg);
9018        return msg;
9019    }
9020
9021    /**
9022     * Returns if the ContentProvider has granted a uri to callingUid
9023     */
9024    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9025        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9026        if (perms != null) {
9027            for (int i=perms.size()-1; i>=0; i--) {
9028                GrantUri grantUri = perms.keyAt(i);
9029                if (grantUri.sourceUserId == userId || !checkUser) {
9030                    if (matchesProvider(grantUri.uri, cpi)) {
9031                        return true;
9032                    }
9033                }
9034            }
9035        }
9036        return false;
9037    }
9038
9039    /**
9040     * Returns true if the uri authority is one of the authorities specified in the provider.
9041     */
9042    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9043        String uriAuth = uri.getAuthority();
9044        String cpiAuth = cpi.authority;
9045        if (cpiAuth.indexOf(';') == -1) {
9046            return cpiAuth.equals(uriAuth);
9047        }
9048        String[] cpiAuths = cpiAuth.split(";");
9049        int length = cpiAuths.length;
9050        for (int i = 0; i < length; i++) {
9051            if (cpiAuths[i].equals(uriAuth)) return true;
9052        }
9053        return false;
9054    }
9055
9056    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9057            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9058        if (r != null) {
9059            for (int i=0; i<r.conProviders.size(); i++) {
9060                ContentProviderConnection conn = r.conProviders.get(i);
9061                if (conn.provider == cpr) {
9062                    if (DEBUG_PROVIDER) Slog.v(TAG,
9063                            "Adding provider requested by "
9064                            + r.processName + " from process "
9065                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9066                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9067                    if (stable) {
9068                        conn.stableCount++;
9069                        conn.numStableIncs++;
9070                    } else {
9071                        conn.unstableCount++;
9072                        conn.numUnstableIncs++;
9073                    }
9074                    return conn;
9075                }
9076            }
9077            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9078            if (stable) {
9079                conn.stableCount = 1;
9080                conn.numStableIncs = 1;
9081            } else {
9082                conn.unstableCount = 1;
9083                conn.numUnstableIncs = 1;
9084            }
9085            cpr.connections.add(conn);
9086            r.conProviders.add(conn);
9087            return conn;
9088        }
9089        cpr.addExternalProcessHandleLocked(externalProcessToken);
9090        return null;
9091    }
9092
9093    boolean decProviderCountLocked(ContentProviderConnection conn,
9094            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9095        if (conn != null) {
9096            cpr = conn.provider;
9097            if (DEBUG_PROVIDER) Slog.v(TAG,
9098                    "Removing provider requested by "
9099                    + conn.client.processName + " from process "
9100                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9101                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9102            if (stable) {
9103                conn.stableCount--;
9104            } else {
9105                conn.unstableCount--;
9106            }
9107            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9108                cpr.connections.remove(conn);
9109                conn.client.conProviders.remove(conn);
9110                return true;
9111            }
9112            return false;
9113        }
9114        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9115        return false;
9116    }
9117
9118    private void checkTime(long startTime, String where) {
9119        long now = SystemClock.elapsedRealtime();
9120        if ((now-startTime) > 1000) {
9121            // If we are taking more than a second, log about it.
9122            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9123        }
9124    }
9125
9126    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9127            String name, IBinder token, boolean stable, int userId) {
9128        ContentProviderRecord cpr;
9129        ContentProviderConnection conn = null;
9130        ProviderInfo cpi = null;
9131
9132        synchronized(this) {
9133            long startTime = SystemClock.elapsedRealtime();
9134
9135            ProcessRecord r = null;
9136            if (caller != null) {
9137                r = getRecordForAppLocked(caller);
9138                if (r == null) {
9139                    throw new SecurityException(
9140                            "Unable to find app for caller " + caller
9141                          + " (pid=" + Binder.getCallingPid()
9142                          + ") when getting content provider " + name);
9143                }
9144            }
9145
9146            boolean checkCrossUser = true;
9147
9148            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9149
9150            // First check if this content provider has been published...
9151            cpr = mProviderMap.getProviderByName(name, userId);
9152            // If that didn't work, check if it exists for user 0 and then
9153            // verify that it's a singleton provider before using it.
9154            if (cpr == null && userId != UserHandle.USER_OWNER) {
9155                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9156                if (cpr != null) {
9157                    cpi = cpr.info;
9158                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9159                            cpi.name, cpi.flags)
9160                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9161                        userId = UserHandle.USER_OWNER;
9162                        checkCrossUser = false;
9163                    } else {
9164                        cpr = null;
9165                        cpi = null;
9166                    }
9167                }
9168            }
9169
9170            boolean providerRunning = cpr != null;
9171            if (providerRunning) {
9172                cpi = cpr.info;
9173                String msg;
9174                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9175                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9176                        != null) {
9177                    throw new SecurityException(msg);
9178                }
9179                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9180
9181                if (r != null && cpr.canRunHere(r)) {
9182                    // This provider has been published or is in the process
9183                    // of being published...  but it is also allowed to run
9184                    // in the caller's process, so don't make a connection
9185                    // and just let the caller instantiate its own instance.
9186                    ContentProviderHolder holder = cpr.newHolder(null);
9187                    // don't give caller the provider object, it needs
9188                    // to make its own.
9189                    holder.provider = null;
9190                    return holder;
9191                }
9192
9193                final long origId = Binder.clearCallingIdentity();
9194
9195                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9196
9197                // In this case the provider instance already exists, so we can
9198                // return it right away.
9199                conn = incProviderCountLocked(r, cpr, token, stable);
9200                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9201                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9202                        // If this is a perceptible app accessing the provider,
9203                        // make sure to count it as being accessed and thus
9204                        // back up on the LRU list.  This is good because
9205                        // content providers are often expensive to start.
9206                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9207                        updateLruProcessLocked(cpr.proc, false, null);
9208                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9209                    }
9210                }
9211
9212                if (cpr.proc != null) {
9213                    if (false) {
9214                        if (cpr.name.flattenToShortString().equals(
9215                                "com.android.providers.calendar/.CalendarProvider2")) {
9216                            Slog.v(TAG, "****************** KILLING "
9217                                + cpr.name.flattenToShortString());
9218                            Process.killProcess(cpr.proc.pid);
9219                        }
9220                    }
9221                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9222                    boolean success = updateOomAdjLocked(cpr.proc);
9223                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9224                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9225                    // NOTE: there is still a race here where a signal could be
9226                    // pending on the process even though we managed to update its
9227                    // adj level.  Not sure what to do about this, but at least
9228                    // the race is now smaller.
9229                    if (!success) {
9230                        // Uh oh...  it looks like the provider's process
9231                        // has been killed on us.  We need to wait for a new
9232                        // process to be started, and make sure its death
9233                        // doesn't kill our process.
9234                        Slog.i(TAG,
9235                                "Existing provider " + cpr.name.flattenToShortString()
9236                                + " is crashing; detaching " + r);
9237                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9238                        checkTime(startTime, "getContentProviderImpl: before appDied");
9239                        appDiedLocked(cpr.proc);
9240                        checkTime(startTime, "getContentProviderImpl: after appDied");
9241                        if (!lastRef) {
9242                            // This wasn't the last ref our process had on
9243                            // the provider...  we have now been killed, bail.
9244                            return null;
9245                        }
9246                        providerRunning = false;
9247                        conn = null;
9248                    }
9249                }
9250
9251                Binder.restoreCallingIdentity(origId);
9252            }
9253
9254            boolean singleton;
9255            if (!providerRunning) {
9256                try {
9257                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9258                    cpi = AppGlobals.getPackageManager().
9259                        resolveContentProvider(name,
9260                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9261                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9262                } catch (RemoteException ex) {
9263                }
9264                if (cpi == null) {
9265                    return null;
9266                }
9267                // If the provider is a singleton AND
9268                // (it's a call within the same user || the provider is a
9269                // privileged app)
9270                // Then allow connecting to the singleton provider
9271                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9272                        cpi.name, cpi.flags)
9273                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9274                if (singleton) {
9275                    userId = UserHandle.USER_OWNER;
9276                }
9277                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9278                checkTime(startTime, "getContentProviderImpl: got app info for user");
9279
9280                String msg;
9281                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9282                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9283                        != null) {
9284                    throw new SecurityException(msg);
9285                }
9286                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9287
9288                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9289                        && !cpi.processName.equals("system")) {
9290                    // If this content provider does not run in the system
9291                    // process, and the system is not yet ready to run other
9292                    // processes, then fail fast instead of hanging.
9293                    throw new IllegalArgumentException(
9294                            "Attempt to launch content provider before system ready");
9295                }
9296
9297                // Make sure that the user who owns this provider is running.  If not,
9298                // we don't want to allow it to run.
9299                if (!isUserRunningLocked(userId, false)) {
9300                    Slog.w(TAG, "Unable to launch app "
9301                            + cpi.applicationInfo.packageName + "/"
9302                            + cpi.applicationInfo.uid + " for provider "
9303                            + name + ": user " + userId + " is stopped");
9304                    return null;
9305                }
9306
9307                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9308                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9309                cpr = mProviderMap.getProviderByClass(comp, userId);
9310                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9311                final boolean firstClass = cpr == null;
9312                if (firstClass) {
9313                    final long ident = Binder.clearCallingIdentity();
9314                    try {
9315                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9316                        ApplicationInfo ai =
9317                            AppGlobals.getPackageManager().
9318                                getApplicationInfo(
9319                                        cpi.applicationInfo.packageName,
9320                                        STOCK_PM_FLAGS, userId);
9321                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9322                        if (ai == null) {
9323                            Slog.w(TAG, "No package info for content provider "
9324                                    + cpi.name);
9325                            return null;
9326                        }
9327                        ai = getAppInfoForUser(ai, userId);
9328                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9329                    } catch (RemoteException ex) {
9330                        // pm is in same process, this will never happen.
9331                    } finally {
9332                        Binder.restoreCallingIdentity(ident);
9333                    }
9334                }
9335
9336                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9337
9338                if (r != null && cpr.canRunHere(r)) {
9339                    // If this is a multiprocess provider, then just return its
9340                    // info and allow the caller to instantiate it.  Only do
9341                    // this if the provider is the same user as the caller's
9342                    // process, or can run as root (so can be in any process).
9343                    return cpr.newHolder(null);
9344                }
9345
9346                if (DEBUG_PROVIDER) {
9347                    RuntimeException e = new RuntimeException("here");
9348                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9349                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9350                }
9351
9352                // This is single process, and our app is now connecting to it.
9353                // See if we are already in the process of launching this
9354                // provider.
9355                final int N = mLaunchingProviders.size();
9356                int i;
9357                for (i=0; i<N; i++) {
9358                    if (mLaunchingProviders.get(i) == cpr) {
9359                        break;
9360                    }
9361                }
9362
9363                // If the provider is not already being launched, then get it
9364                // started.
9365                if (i >= N) {
9366                    final long origId = Binder.clearCallingIdentity();
9367
9368                    try {
9369                        // Content provider is now in use, its package can't be stopped.
9370                        try {
9371                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9372                            AppGlobals.getPackageManager().setPackageStoppedState(
9373                                    cpr.appInfo.packageName, false, userId);
9374                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9375                        } catch (RemoteException e) {
9376                        } catch (IllegalArgumentException e) {
9377                            Slog.w(TAG, "Failed trying to unstop package "
9378                                    + cpr.appInfo.packageName + ": " + e);
9379                        }
9380
9381                        // Use existing process if already started
9382                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9383                        ProcessRecord proc = getProcessRecordLocked(
9384                                cpi.processName, cpr.appInfo.uid, false);
9385                        if (proc != null && proc.thread != null) {
9386                            if (DEBUG_PROVIDER) {
9387                                Slog.d(TAG, "Installing in existing process " + proc);
9388                            }
9389                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9390                            proc.pubProviders.put(cpi.name, cpr);
9391                            try {
9392                                proc.thread.scheduleInstallProvider(cpi);
9393                            } catch (RemoteException e) {
9394                            }
9395                        } else {
9396                            checkTime(startTime, "getContentProviderImpl: before start process");
9397                            proc = startProcessLocked(cpi.processName,
9398                                    cpr.appInfo, false, 0, "content provider",
9399                                    new ComponentName(cpi.applicationInfo.packageName,
9400                                            cpi.name), false, false, false);
9401                            checkTime(startTime, "getContentProviderImpl: after start process");
9402                            if (proc == null) {
9403                                Slog.w(TAG, "Unable to launch app "
9404                                        + cpi.applicationInfo.packageName + "/"
9405                                        + cpi.applicationInfo.uid + " for provider "
9406                                        + name + ": process is bad");
9407                                return null;
9408                            }
9409                        }
9410                        cpr.launchingApp = proc;
9411                        mLaunchingProviders.add(cpr);
9412                    } finally {
9413                        Binder.restoreCallingIdentity(origId);
9414                    }
9415                }
9416
9417                checkTime(startTime, "getContentProviderImpl: updating data structures");
9418
9419                // Make sure the provider is published (the same provider class
9420                // may be published under multiple names).
9421                if (firstClass) {
9422                    mProviderMap.putProviderByClass(comp, cpr);
9423                }
9424
9425                mProviderMap.putProviderByName(name, cpr);
9426                conn = incProviderCountLocked(r, cpr, token, stable);
9427                if (conn != null) {
9428                    conn.waiting = true;
9429                }
9430            }
9431            checkTime(startTime, "getContentProviderImpl: done!");
9432        }
9433
9434        // Wait for the provider to be published...
9435        synchronized (cpr) {
9436            while (cpr.provider == null) {
9437                if (cpr.launchingApp == null) {
9438                    Slog.w(TAG, "Unable to launch app "
9439                            + cpi.applicationInfo.packageName + "/"
9440                            + cpi.applicationInfo.uid + " for provider "
9441                            + name + ": launching app became null");
9442                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9443                            UserHandle.getUserId(cpi.applicationInfo.uid),
9444                            cpi.applicationInfo.packageName,
9445                            cpi.applicationInfo.uid, name);
9446                    return null;
9447                }
9448                try {
9449                    if (DEBUG_MU) {
9450                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9451                                + cpr.launchingApp);
9452                    }
9453                    if (conn != null) {
9454                        conn.waiting = true;
9455                    }
9456                    cpr.wait();
9457                } catch (InterruptedException ex) {
9458                } finally {
9459                    if (conn != null) {
9460                        conn.waiting = false;
9461                    }
9462                }
9463            }
9464        }
9465        return cpr != null ? cpr.newHolder(conn) : null;
9466    }
9467
9468    @Override
9469    public final ContentProviderHolder getContentProvider(
9470            IApplicationThread caller, String name, int userId, boolean stable) {
9471        enforceNotIsolatedCaller("getContentProvider");
9472        if (caller == null) {
9473            String msg = "null IApplicationThread when getting content provider "
9474                    + name;
9475            Slog.w(TAG, msg);
9476            throw new SecurityException(msg);
9477        }
9478        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9479        // with cross-user grant.
9480        return getContentProviderImpl(caller, name, null, stable, userId);
9481    }
9482
9483    public ContentProviderHolder getContentProviderExternal(
9484            String name, int userId, IBinder token) {
9485        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9486            "Do not have permission in call getContentProviderExternal()");
9487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9488                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9489        return getContentProviderExternalUnchecked(name, token, userId);
9490    }
9491
9492    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9493            IBinder token, int userId) {
9494        return getContentProviderImpl(null, name, token, true, userId);
9495    }
9496
9497    /**
9498     * Drop a content provider from a ProcessRecord's bookkeeping
9499     */
9500    public void removeContentProvider(IBinder connection, boolean stable) {
9501        enforceNotIsolatedCaller("removeContentProvider");
9502        long ident = Binder.clearCallingIdentity();
9503        try {
9504            synchronized (this) {
9505                ContentProviderConnection conn;
9506                try {
9507                    conn = (ContentProviderConnection)connection;
9508                } catch (ClassCastException e) {
9509                    String msg ="removeContentProvider: " + connection
9510                            + " not a ContentProviderConnection";
9511                    Slog.w(TAG, msg);
9512                    throw new IllegalArgumentException(msg);
9513                }
9514                if (conn == null) {
9515                    throw new NullPointerException("connection is null");
9516                }
9517                if (decProviderCountLocked(conn, null, null, stable)) {
9518                    updateOomAdjLocked();
9519                }
9520            }
9521        } finally {
9522            Binder.restoreCallingIdentity(ident);
9523        }
9524    }
9525
9526    public void removeContentProviderExternal(String name, IBinder token) {
9527        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9528            "Do not have permission in call removeContentProviderExternal()");
9529        int userId = UserHandle.getCallingUserId();
9530        long ident = Binder.clearCallingIdentity();
9531        try {
9532            removeContentProviderExternalUnchecked(name, token, userId);
9533        } finally {
9534            Binder.restoreCallingIdentity(ident);
9535        }
9536    }
9537
9538    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9539        synchronized (this) {
9540            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9541            if(cpr == null) {
9542                //remove from mProvidersByClass
9543                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9544                return;
9545            }
9546
9547            //update content provider record entry info
9548            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9549            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9550            if (localCpr.hasExternalProcessHandles()) {
9551                if (localCpr.removeExternalProcessHandleLocked(token)) {
9552                    updateOomAdjLocked();
9553                } else {
9554                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9555                            + " with no external reference for token: "
9556                            + token + ".");
9557                }
9558            } else {
9559                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9560                        + " with no external references.");
9561            }
9562        }
9563    }
9564
9565    public final void publishContentProviders(IApplicationThread caller,
9566            List<ContentProviderHolder> providers) {
9567        if (providers == null) {
9568            return;
9569        }
9570
9571        enforceNotIsolatedCaller("publishContentProviders");
9572        synchronized (this) {
9573            final ProcessRecord r = getRecordForAppLocked(caller);
9574            if (DEBUG_MU)
9575                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9576            if (r == null) {
9577                throw new SecurityException(
9578                        "Unable to find app for caller " + caller
9579                      + " (pid=" + Binder.getCallingPid()
9580                      + ") when publishing content providers");
9581            }
9582
9583            final long origId = Binder.clearCallingIdentity();
9584
9585            final int N = providers.size();
9586            for (int i=0; i<N; i++) {
9587                ContentProviderHolder src = providers.get(i);
9588                if (src == null || src.info == null || src.provider == null) {
9589                    continue;
9590                }
9591                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9592                if (DEBUG_MU)
9593                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9594                if (dst != null) {
9595                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9596                    mProviderMap.putProviderByClass(comp, dst);
9597                    String names[] = dst.info.authority.split(";");
9598                    for (int j = 0; j < names.length; j++) {
9599                        mProviderMap.putProviderByName(names[j], dst);
9600                    }
9601
9602                    int NL = mLaunchingProviders.size();
9603                    int j;
9604                    for (j=0; j<NL; j++) {
9605                        if (mLaunchingProviders.get(j) == dst) {
9606                            mLaunchingProviders.remove(j);
9607                            j--;
9608                            NL--;
9609                        }
9610                    }
9611                    synchronized (dst) {
9612                        dst.provider = src.provider;
9613                        dst.proc = r;
9614                        dst.notifyAll();
9615                    }
9616                    updateOomAdjLocked(r);
9617                }
9618            }
9619
9620            Binder.restoreCallingIdentity(origId);
9621        }
9622    }
9623
9624    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9625        ContentProviderConnection conn;
9626        try {
9627            conn = (ContentProviderConnection)connection;
9628        } catch (ClassCastException e) {
9629            String msg ="refContentProvider: " + connection
9630                    + " not a ContentProviderConnection";
9631            Slog.w(TAG, msg);
9632            throw new IllegalArgumentException(msg);
9633        }
9634        if (conn == null) {
9635            throw new NullPointerException("connection is null");
9636        }
9637
9638        synchronized (this) {
9639            if (stable > 0) {
9640                conn.numStableIncs += stable;
9641            }
9642            stable = conn.stableCount + stable;
9643            if (stable < 0) {
9644                throw new IllegalStateException("stableCount < 0: " + stable);
9645            }
9646
9647            if (unstable > 0) {
9648                conn.numUnstableIncs += unstable;
9649            }
9650            unstable = conn.unstableCount + unstable;
9651            if (unstable < 0) {
9652                throw new IllegalStateException("unstableCount < 0: " + unstable);
9653            }
9654
9655            if ((stable+unstable) <= 0) {
9656                throw new IllegalStateException("ref counts can't go to zero here: stable="
9657                        + stable + " unstable=" + unstable);
9658            }
9659            conn.stableCount = stable;
9660            conn.unstableCount = unstable;
9661            return !conn.dead;
9662        }
9663    }
9664
9665    public void unstableProviderDied(IBinder connection) {
9666        ContentProviderConnection conn;
9667        try {
9668            conn = (ContentProviderConnection)connection;
9669        } catch (ClassCastException e) {
9670            String msg ="refContentProvider: " + connection
9671                    + " not a ContentProviderConnection";
9672            Slog.w(TAG, msg);
9673            throw new IllegalArgumentException(msg);
9674        }
9675        if (conn == null) {
9676            throw new NullPointerException("connection is null");
9677        }
9678
9679        // Safely retrieve the content provider associated with the connection.
9680        IContentProvider provider;
9681        synchronized (this) {
9682            provider = conn.provider.provider;
9683        }
9684
9685        if (provider == null) {
9686            // Um, yeah, we're way ahead of you.
9687            return;
9688        }
9689
9690        // Make sure the caller is being honest with us.
9691        if (provider.asBinder().pingBinder()) {
9692            // Er, no, still looks good to us.
9693            synchronized (this) {
9694                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9695                        + " says " + conn + " died, but we don't agree");
9696                return;
9697            }
9698        }
9699
9700        // Well look at that!  It's dead!
9701        synchronized (this) {
9702            if (conn.provider.provider != provider) {
9703                // But something changed...  good enough.
9704                return;
9705            }
9706
9707            ProcessRecord proc = conn.provider.proc;
9708            if (proc == null || proc.thread == null) {
9709                // Seems like the process is already cleaned up.
9710                return;
9711            }
9712
9713            // As far as we're concerned, this is just like receiving a
9714            // death notification...  just a bit prematurely.
9715            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9716                    + ") early provider death");
9717            final long ident = Binder.clearCallingIdentity();
9718            try {
9719                appDiedLocked(proc);
9720            } finally {
9721                Binder.restoreCallingIdentity(ident);
9722            }
9723        }
9724    }
9725
9726    @Override
9727    public void appNotRespondingViaProvider(IBinder connection) {
9728        enforceCallingPermission(
9729                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9730
9731        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9732        if (conn == null) {
9733            Slog.w(TAG, "ContentProviderConnection is null");
9734            return;
9735        }
9736
9737        final ProcessRecord host = conn.provider.proc;
9738        if (host == null) {
9739            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9740            return;
9741        }
9742
9743        final long token = Binder.clearCallingIdentity();
9744        try {
9745            appNotResponding(host, null, null, false, "ContentProvider not responding");
9746        } finally {
9747            Binder.restoreCallingIdentity(token);
9748        }
9749    }
9750
9751    public final void installSystemProviders() {
9752        List<ProviderInfo> providers;
9753        synchronized (this) {
9754            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9755            providers = generateApplicationProvidersLocked(app);
9756            if (providers != null) {
9757                for (int i=providers.size()-1; i>=0; i--) {
9758                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9759                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9760                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9761                                + ": not system .apk");
9762                        providers.remove(i);
9763                    }
9764                }
9765            }
9766        }
9767        if (providers != null) {
9768            mSystemThread.installSystemProviders(providers);
9769        }
9770
9771        mCoreSettingsObserver = new CoreSettingsObserver(this);
9772
9773        //mUsageStatsService.monitorPackages();
9774    }
9775
9776    /**
9777     * Allows apps to retrieve the MIME type of a URI.
9778     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9779     * users, then it does not need permission to access the ContentProvider.
9780     * Either, it needs cross-user uri grants.
9781     *
9782     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9783     *
9784     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9785     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9786     */
9787    public String getProviderMimeType(Uri uri, int userId) {
9788        enforceNotIsolatedCaller("getProviderMimeType");
9789        final String name = uri.getAuthority();
9790        int callingUid = Binder.getCallingUid();
9791        int callingPid = Binder.getCallingPid();
9792        long ident = 0;
9793        boolean clearedIdentity = false;
9794        userId = unsafeConvertIncomingUser(userId);
9795        if (canClearIdentity(callingPid, callingUid, userId)) {
9796            clearedIdentity = true;
9797            ident = Binder.clearCallingIdentity();
9798        }
9799        ContentProviderHolder holder = null;
9800        try {
9801            holder = getContentProviderExternalUnchecked(name, null, userId);
9802            if (holder != null) {
9803                return holder.provider.getType(uri);
9804            }
9805        } catch (RemoteException e) {
9806            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9807            return null;
9808        } finally {
9809            // We need to clear the identity to call removeContentProviderExternalUnchecked
9810            if (!clearedIdentity) {
9811                ident = Binder.clearCallingIdentity();
9812            }
9813            try {
9814                if (holder != null) {
9815                    removeContentProviderExternalUnchecked(name, null, userId);
9816                }
9817            } finally {
9818                Binder.restoreCallingIdentity(ident);
9819            }
9820        }
9821
9822        return null;
9823    }
9824
9825    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9826        if (UserHandle.getUserId(callingUid) == userId) {
9827            return true;
9828        }
9829        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9830                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9831                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9832                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9833                return true;
9834        }
9835        return false;
9836    }
9837
9838    // =========================================================
9839    // GLOBAL MANAGEMENT
9840    // =========================================================
9841
9842    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9843            boolean isolated, int isolatedUid) {
9844        String proc = customProcess != null ? customProcess : info.processName;
9845        BatteryStatsImpl.Uid.Proc ps = null;
9846        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9847        int uid = info.uid;
9848        if (isolated) {
9849            if (isolatedUid == 0) {
9850                int userId = UserHandle.getUserId(uid);
9851                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9852                while (true) {
9853                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9854                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9855                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9856                    }
9857                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9858                    mNextIsolatedProcessUid++;
9859                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9860                        // No process for this uid, use it.
9861                        break;
9862                    }
9863                    stepsLeft--;
9864                    if (stepsLeft <= 0) {
9865                        return null;
9866                    }
9867                }
9868            } else {
9869                // Special case for startIsolatedProcess (internal only), where
9870                // the uid of the isolated process is specified by the caller.
9871                uid = isolatedUid;
9872            }
9873        }
9874        return new ProcessRecord(stats, info, proc, uid);
9875    }
9876
9877    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9878            String abiOverride) {
9879        ProcessRecord app;
9880        if (!isolated) {
9881            app = getProcessRecordLocked(info.processName, info.uid, true);
9882        } else {
9883            app = null;
9884        }
9885
9886        if (app == null) {
9887            app = newProcessRecordLocked(info, null, isolated, 0);
9888            mProcessNames.put(info.processName, app.uid, app);
9889            if (isolated) {
9890                mIsolatedProcesses.put(app.uid, app);
9891            }
9892            updateLruProcessLocked(app, false, null);
9893            updateOomAdjLocked();
9894        }
9895
9896        // This package really, really can not be stopped.
9897        try {
9898            AppGlobals.getPackageManager().setPackageStoppedState(
9899                    info.packageName, false, UserHandle.getUserId(app.uid));
9900        } catch (RemoteException e) {
9901        } catch (IllegalArgumentException e) {
9902            Slog.w(TAG, "Failed trying to unstop package "
9903                    + info.packageName + ": " + e);
9904        }
9905
9906        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9907                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9908            app.persistent = true;
9909            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9910        }
9911        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9912            mPersistentStartingProcesses.add(app);
9913            startProcessLocked(app, "added application", app.processName, abiOverride,
9914                    null /* entryPoint */, null /* entryPointArgs */);
9915        }
9916
9917        return app;
9918    }
9919
9920    public void unhandledBack() {
9921        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9922                "unhandledBack()");
9923
9924        synchronized(this) {
9925            final long origId = Binder.clearCallingIdentity();
9926            try {
9927                getFocusedStack().unhandledBackLocked();
9928            } finally {
9929                Binder.restoreCallingIdentity(origId);
9930            }
9931        }
9932    }
9933
9934    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9935        enforceNotIsolatedCaller("openContentUri");
9936        final int userId = UserHandle.getCallingUserId();
9937        String name = uri.getAuthority();
9938        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9939        ParcelFileDescriptor pfd = null;
9940        if (cph != null) {
9941            // We record the binder invoker's uid in thread-local storage before
9942            // going to the content provider to open the file.  Later, in the code
9943            // that handles all permissions checks, we look for this uid and use
9944            // that rather than the Activity Manager's own uid.  The effect is that
9945            // we do the check against the caller's permissions even though it looks
9946            // to the content provider like the Activity Manager itself is making
9947            // the request.
9948            Binder token = new Binder();
9949            sCallerIdentity.set(new Identity(
9950                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9951            try {
9952                pfd = cph.provider.openFile(null, uri, "r", null, token);
9953            } catch (FileNotFoundException e) {
9954                // do nothing; pfd will be returned null
9955            } finally {
9956                // Ensure that whatever happens, we clean up the identity state
9957                sCallerIdentity.remove();
9958            }
9959
9960            // We've got the fd now, so we're done with the provider.
9961            removeContentProviderExternalUnchecked(name, null, userId);
9962        } else {
9963            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9964        }
9965        return pfd;
9966    }
9967
9968    // Actually is sleeping or shutting down or whatever else in the future
9969    // is an inactive state.
9970    public boolean isSleepingOrShuttingDown() {
9971        return isSleeping() || mShuttingDown;
9972    }
9973
9974    public boolean isSleeping() {
9975        return mSleeping;
9976    }
9977
9978    void onWakefulnessChanged(int wakefulness) {
9979        synchronized(this) {
9980            mWakefulness = wakefulness;
9981            updateSleepIfNeededLocked();
9982        }
9983    }
9984
9985    void finishRunningVoiceLocked() {
9986        if (mRunningVoice) {
9987            mRunningVoice = false;
9988            updateSleepIfNeededLocked();
9989        }
9990    }
9991
9992    void updateSleepIfNeededLocked() {
9993        if (mSleeping && !shouldSleepLocked()) {
9994            mSleeping = false;
9995            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9996        } else if (!mSleeping && shouldSleepLocked()) {
9997            mSleeping = true;
9998            mStackSupervisor.goingToSleepLocked();
9999
10000            // Initialize the wake times of all processes.
10001            checkExcessivePowerUsageLocked(false);
10002            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10003            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10004            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10005        }
10006    }
10007
10008    private boolean shouldSleepLocked() {
10009        // Resume applications while running a voice interactor.
10010        if (mRunningVoice) {
10011            return false;
10012        }
10013
10014        switch (mWakefulness) {
10015            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10016            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10017                // If we're interactive but applications are already paused then defer
10018                // resuming them until the lock screen is hidden.
10019                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10020            case PowerManagerInternal.WAKEFULNESS_DOZING:
10021                // If we're dozing then pause applications whenever the lock screen is shown.
10022                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10023            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10024            default:
10025                // If we're asleep then pause applications unconditionally.
10026                return true;
10027        }
10028    }
10029
10030    /** Pokes the task persister. */
10031    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10032        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10033            // Never persist the home stack.
10034            return;
10035        }
10036        mTaskPersister.wakeup(task, flush);
10037    }
10038
10039    /** Notifies all listeners when the task stack has changed. */
10040    void notifyTaskStackChangedLocked() {
10041        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10042        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10043        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10044    }
10045
10046    @Override
10047    public boolean shutdown(int timeout) {
10048        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10049                != PackageManager.PERMISSION_GRANTED) {
10050            throw new SecurityException("Requires permission "
10051                    + android.Manifest.permission.SHUTDOWN);
10052        }
10053
10054        boolean timedout = false;
10055
10056        synchronized(this) {
10057            mShuttingDown = true;
10058            updateEventDispatchingLocked();
10059            timedout = mStackSupervisor.shutdownLocked(timeout);
10060        }
10061
10062        mAppOpsService.shutdown();
10063        if (mUsageStatsService != null) {
10064            mUsageStatsService.prepareShutdown();
10065        }
10066        mBatteryStatsService.shutdown();
10067        synchronized (this) {
10068            mProcessStats.shutdownLocked();
10069            notifyTaskPersisterLocked(null, true);
10070        }
10071
10072        return timedout;
10073    }
10074
10075    public final void activitySlept(IBinder token) {
10076        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10077
10078        final long origId = Binder.clearCallingIdentity();
10079
10080        synchronized (this) {
10081            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10082            if (r != null) {
10083                mStackSupervisor.activitySleptLocked(r);
10084            }
10085        }
10086
10087        Binder.restoreCallingIdentity(origId);
10088    }
10089
10090    private String lockScreenShownToString() {
10091        switch (mLockScreenShown) {
10092            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10093            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10094            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10095            default: return "Unknown=" + mLockScreenShown;
10096        }
10097    }
10098
10099    void logLockScreen(String msg) {
10100        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10101                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10102                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10103                + " mSleeping=" + mSleeping);
10104    }
10105
10106    void startRunningVoiceLocked() {
10107        if (!mRunningVoice) {
10108            mRunningVoice = true;
10109            updateSleepIfNeededLocked();
10110        }
10111    }
10112
10113    private void updateEventDispatchingLocked() {
10114        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10115    }
10116
10117    public void setLockScreenShown(boolean shown) {
10118        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10119                != PackageManager.PERMISSION_GRANTED) {
10120            throw new SecurityException("Requires permission "
10121                    + android.Manifest.permission.DEVICE_POWER);
10122        }
10123
10124        synchronized(this) {
10125            long ident = Binder.clearCallingIdentity();
10126            try {
10127                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10128                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10129                updateSleepIfNeededLocked();
10130            } finally {
10131                Binder.restoreCallingIdentity(ident);
10132            }
10133        }
10134    }
10135
10136    @Override
10137    public void stopAppSwitches() {
10138        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10139                != PackageManager.PERMISSION_GRANTED) {
10140            throw new SecurityException("Requires permission "
10141                    + android.Manifest.permission.STOP_APP_SWITCHES);
10142        }
10143
10144        synchronized(this) {
10145            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10146                    + APP_SWITCH_DELAY_TIME;
10147            mDidAppSwitch = false;
10148            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10149            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10150            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10151        }
10152    }
10153
10154    public void resumeAppSwitches() {
10155        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10156                != PackageManager.PERMISSION_GRANTED) {
10157            throw new SecurityException("Requires permission "
10158                    + android.Manifest.permission.STOP_APP_SWITCHES);
10159        }
10160
10161        synchronized(this) {
10162            // Note that we don't execute any pending app switches... we will
10163            // let those wait until either the timeout, or the next start
10164            // activity request.
10165            mAppSwitchesAllowedTime = 0;
10166        }
10167    }
10168
10169    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10170            int callingPid, int callingUid, String name) {
10171        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10172            return true;
10173        }
10174
10175        int perm = checkComponentPermission(
10176                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10177                sourceUid, -1, true);
10178        if (perm == PackageManager.PERMISSION_GRANTED) {
10179            return true;
10180        }
10181
10182        // If the actual IPC caller is different from the logical source, then
10183        // also see if they are allowed to control app switches.
10184        if (callingUid != -1 && callingUid != sourceUid) {
10185            perm = checkComponentPermission(
10186                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10187                    callingUid, -1, true);
10188            if (perm == PackageManager.PERMISSION_GRANTED) {
10189                return true;
10190            }
10191        }
10192
10193        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10194        return false;
10195    }
10196
10197    public void setDebugApp(String packageName, boolean waitForDebugger,
10198            boolean persistent) {
10199        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10200                "setDebugApp()");
10201
10202        long ident = Binder.clearCallingIdentity();
10203        try {
10204            // Note that this is not really thread safe if there are multiple
10205            // callers into it at the same time, but that's not a situation we
10206            // care about.
10207            if (persistent) {
10208                final ContentResolver resolver = mContext.getContentResolver();
10209                Settings.Global.putString(
10210                    resolver, Settings.Global.DEBUG_APP,
10211                    packageName);
10212                Settings.Global.putInt(
10213                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10214                    waitForDebugger ? 1 : 0);
10215            }
10216
10217            synchronized (this) {
10218                if (!persistent) {
10219                    mOrigDebugApp = mDebugApp;
10220                    mOrigWaitForDebugger = mWaitForDebugger;
10221                }
10222                mDebugApp = packageName;
10223                mWaitForDebugger = waitForDebugger;
10224                mDebugTransient = !persistent;
10225                if (packageName != null) {
10226                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10227                            false, UserHandle.USER_ALL, "set debug app");
10228                }
10229            }
10230        } finally {
10231            Binder.restoreCallingIdentity(ident);
10232        }
10233    }
10234
10235    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10236        synchronized (this) {
10237            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10238            if (!isDebuggable) {
10239                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10240                    throw new SecurityException("Process not debuggable: " + app.packageName);
10241                }
10242            }
10243
10244            mOpenGlTraceApp = processName;
10245        }
10246    }
10247
10248    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10249        synchronized (this) {
10250            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10251            if (!isDebuggable) {
10252                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10253                    throw new SecurityException("Process not debuggable: " + app.packageName);
10254                }
10255            }
10256            mProfileApp = processName;
10257            mProfileFile = profilerInfo.profileFile;
10258            if (mProfileFd != null) {
10259                try {
10260                    mProfileFd.close();
10261                } catch (IOException e) {
10262                }
10263                mProfileFd = null;
10264            }
10265            mProfileFd = profilerInfo.profileFd;
10266            mSamplingInterval = profilerInfo.samplingInterval;
10267            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10268            mProfileType = 0;
10269        }
10270    }
10271
10272    @Override
10273    public void setAlwaysFinish(boolean enabled) {
10274        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10275                "setAlwaysFinish()");
10276
10277        Settings.Global.putInt(
10278                mContext.getContentResolver(),
10279                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10280
10281        synchronized (this) {
10282            mAlwaysFinishActivities = enabled;
10283        }
10284    }
10285
10286    @Override
10287    public void setActivityController(IActivityController controller) {
10288        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10289                "setActivityController()");
10290        synchronized (this) {
10291            mController = controller;
10292            Watchdog.getInstance().setActivityController(controller);
10293        }
10294    }
10295
10296    @Override
10297    public void setUserIsMonkey(boolean userIsMonkey) {
10298        synchronized (this) {
10299            synchronized (mPidsSelfLocked) {
10300                final int callingPid = Binder.getCallingPid();
10301                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10302                if (precessRecord == null) {
10303                    throw new SecurityException("Unknown process: " + callingPid);
10304                }
10305                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10306                    throw new SecurityException("Only an instrumentation process "
10307                            + "with a UiAutomation can call setUserIsMonkey");
10308                }
10309            }
10310            mUserIsMonkey = userIsMonkey;
10311        }
10312    }
10313
10314    @Override
10315    public boolean isUserAMonkey() {
10316        synchronized (this) {
10317            // If there is a controller also implies the user is a monkey.
10318            return (mUserIsMonkey || mController != null);
10319        }
10320    }
10321
10322    public void requestBugReport() {
10323        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10324        SystemProperties.set("ctl.start", "bugreport");
10325    }
10326
10327    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10328        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10329    }
10330
10331    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10332        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10333            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10334        }
10335        return KEY_DISPATCHING_TIMEOUT;
10336    }
10337
10338    @Override
10339    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10340        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10341                != PackageManager.PERMISSION_GRANTED) {
10342            throw new SecurityException("Requires permission "
10343                    + android.Manifest.permission.FILTER_EVENTS);
10344        }
10345        ProcessRecord proc;
10346        long timeout;
10347        synchronized (this) {
10348            synchronized (mPidsSelfLocked) {
10349                proc = mPidsSelfLocked.get(pid);
10350            }
10351            timeout = getInputDispatchingTimeoutLocked(proc);
10352        }
10353
10354        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10355            return -1;
10356        }
10357
10358        return timeout;
10359    }
10360
10361    /**
10362     * Handle input dispatching timeouts.
10363     * Returns whether input dispatching should be aborted or not.
10364     */
10365    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10366            final ActivityRecord activity, final ActivityRecord parent,
10367            final boolean aboveSystem, String reason) {
10368        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10369                != PackageManager.PERMISSION_GRANTED) {
10370            throw new SecurityException("Requires permission "
10371                    + android.Manifest.permission.FILTER_EVENTS);
10372        }
10373
10374        final String annotation;
10375        if (reason == null) {
10376            annotation = "Input dispatching timed out";
10377        } else {
10378            annotation = "Input dispatching timed out (" + reason + ")";
10379        }
10380
10381        if (proc != null) {
10382            synchronized (this) {
10383                if (proc.debugging) {
10384                    return false;
10385                }
10386
10387                if (mDidDexOpt) {
10388                    // Give more time since we were dexopting.
10389                    mDidDexOpt = false;
10390                    return false;
10391                }
10392
10393                if (proc.instrumentationClass != null) {
10394                    Bundle info = new Bundle();
10395                    info.putString("shortMsg", "keyDispatchingTimedOut");
10396                    info.putString("longMsg", annotation);
10397                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10398                    return true;
10399                }
10400            }
10401            mHandler.post(new Runnable() {
10402                @Override
10403                public void run() {
10404                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10405                }
10406            });
10407        }
10408
10409        return true;
10410    }
10411
10412    public Bundle getAssistContextExtras(int requestType) {
10413        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10414                UserHandle.getCallingUserId());
10415        if (pae == null) {
10416            return null;
10417        }
10418        synchronized (pae) {
10419            while (!pae.haveResult) {
10420                try {
10421                    pae.wait();
10422                } catch (InterruptedException e) {
10423                }
10424            }
10425            if (pae.result != null) {
10426                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10427            }
10428        }
10429        synchronized (this) {
10430            mPendingAssistExtras.remove(pae);
10431            mHandler.removeCallbacks(pae);
10432        }
10433        return pae.extras;
10434    }
10435
10436    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10437            int userHandle) {
10438        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10439                "getAssistContextExtras()");
10440        PendingAssistExtras pae;
10441        Bundle extras = new Bundle();
10442        synchronized (this) {
10443            ActivityRecord activity = getFocusedStack().mResumedActivity;
10444            if (activity == null) {
10445                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10446                return null;
10447            }
10448            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10449            if (activity.app == null || activity.app.thread == null) {
10450                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10451                return null;
10452            }
10453            if (activity.app.pid == Binder.getCallingPid()) {
10454                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10455                return null;
10456            }
10457            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10458            try {
10459                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10460                        requestType);
10461                mPendingAssistExtras.add(pae);
10462                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10463            } catch (RemoteException e) {
10464                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10465                return null;
10466            }
10467            return pae;
10468        }
10469    }
10470
10471    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10472        PendingAssistExtras pae = (PendingAssistExtras)token;
10473        synchronized (pae) {
10474            pae.result = extras;
10475            pae.haveResult = true;
10476            pae.notifyAll();
10477            if (pae.intent == null) {
10478                // Caller is just waiting for the result.
10479                return;
10480            }
10481        }
10482
10483        // We are now ready to launch the assist activity.
10484        synchronized (this) {
10485            boolean exists = mPendingAssistExtras.remove(pae);
10486            mHandler.removeCallbacks(pae);
10487            if (!exists) {
10488                // Timed out.
10489                return;
10490            }
10491        }
10492        pae.intent.replaceExtras(extras);
10493        if (pae.hint != null) {
10494            pae.intent.putExtra(pae.hint, true);
10495        }
10496        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10497                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10498                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10499        closeSystemDialogs("assist");
10500        try {
10501            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10502        } catch (ActivityNotFoundException e) {
10503            Slog.w(TAG, "No activity to handle assist action.", e);
10504        }
10505    }
10506
10507    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10508        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10509    }
10510
10511    public void registerProcessObserver(IProcessObserver observer) {
10512        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10513                "registerProcessObserver()");
10514        synchronized (this) {
10515            mProcessObservers.register(observer);
10516        }
10517    }
10518
10519    @Override
10520    public void unregisterProcessObserver(IProcessObserver observer) {
10521        synchronized (this) {
10522            mProcessObservers.unregister(observer);
10523        }
10524    }
10525
10526    @Override
10527    public boolean convertFromTranslucent(IBinder token) {
10528        final long origId = Binder.clearCallingIdentity();
10529        try {
10530            synchronized (this) {
10531                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10532                if (r == null) {
10533                    return false;
10534                }
10535                final boolean translucentChanged = r.changeWindowTranslucency(true);
10536                if (translucentChanged) {
10537                    r.task.stack.releaseBackgroundResources();
10538                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10539                }
10540                mWindowManager.setAppFullscreen(token, true);
10541                return translucentChanged;
10542            }
10543        } finally {
10544            Binder.restoreCallingIdentity(origId);
10545        }
10546    }
10547
10548    @Override
10549    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10550        final long origId = Binder.clearCallingIdentity();
10551        try {
10552            synchronized (this) {
10553                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10554                if (r == null) {
10555                    return false;
10556                }
10557                int index = r.task.mActivities.lastIndexOf(r);
10558                if (index > 0) {
10559                    ActivityRecord under = r.task.mActivities.get(index - 1);
10560                    under.returningOptions = options;
10561                }
10562                final boolean translucentChanged = r.changeWindowTranslucency(false);
10563                if (translucentChanged) {
10564                    r.task.stack.convertToTranslucent(r);
10565                }
10566                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10567                mWindowManager.setAppFullscreen(token, false);
10568                return translucentChanged;
10569            }
10570        } finally {
10571            Binder.restoreCallingIdentity(origId);
10572        }
10573    }
10574
10575    @Override
10576    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10577        final long origId = Binder.clearCallingIdentity();
10578        try {
10579            synchronized (this) {
10580                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10581                if (r != null) {
10582                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10583                }
10584            }
10585            return false;
10586        } finally {
10587            Binder.restoreCallingIdentity(origId);
10588        }
10589    }
10590
10591    @Override
10592    public boolean isBackgroundVisibleBehind(IBinder token) {
10593        final long origId = Binder.clearCallingIdentity();
10594        try {
10595            synchronized (this) {
10596                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10597                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10598                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10599                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10600                return visible;
10601            }
10602        } finally {
10603            Binder.restoreCallingIdentity(origId);
10604        }
10605    }
10606
10607    @Override
10608    public ActivityOptions getActivityOptions(IBinder token) {
10609        final long origId = Binder.clearCallingIdentity();
10610        try {
10611            synchronized (this) {
10612                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10613                if (r != null) {
10614                    final ActivityOptions activityOptions = r.pendingOptions;
10615                    r.pendingOptions = null;
10616                    return activityOptions;
10617                }
10618                return null;
10619            }
10620        } finally {
10621            Binder.restoreCallingIdentity(origId);
10622        }
10623    }
10624
10625    @Override
10626    public void setImmersive(IBinder token, boolean immersive) {
10627        synchronized(this) {
10628            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10629            if (r == null) {
10630                throw new IllegalArgumentException();
10631            }
10632            r.immersive = immersive;
10633
10634            // update associated state if we're frontmost
10635            if (r == mFocusedActivity) {
10636                if (DEBUG_IMMERSIVE) {
10637                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10638                }
10639                applyUpdateLockStateLocked(r);
10640            }
10641        }
10642    }
10643
10644    @Override
10645    public boolean isImmersive(IBinder token) {
10646        synchronized (this) {
10647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10648            if (r == null) {
10649                throw new IllegalArgumentException();
10650            }
10651            return r.immersive;
10652        }
10653    }
10654
10655    public boolean isTopActivityImmersive() {
10656        enforceNotIsolatedCaller("startActivity");
10657        synchronized (this) {
10658            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10659            return (r != null) ? r.immersive : false;
10660        }
10661    }
10662
10663    @Override
10664    public boolean isTopOfTask(IBinder token) {
10665        synchronized (this) {
10666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10667            if (r == null) {
10668                throw new IllegalArgumentException();
10669            }
10670            return r.task.getTopActivity() == r;
10671        }
10672    }
10673
10674    public final void enterSafeMode() {
10675        synchronized(this) {
10676            // It only makes sense to do this before the system is ready
10677            // and started launching other packages.
10678            if (!mSystemReady) {
10679                try {
10680                    AppGlobals.getPackageManager().enterSafeMode();
10681                } catch (RemoteException e) {
10682                }
10683            }
10684
10685            mSafeMode = true;
10686        }
10687    }
10688
10689    public final void showSafeModeOverlay() {
10690        View v = LayoutInflater.from(mContext).inflate(
10691                com.android.internal.R.layout.safe_mode, null);
10692        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10693        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10694        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10695        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10696        lp.gravity = Gravity.BOTTOM | Gravity.START;
10697        lp.format = v.getBackground().getOpacity();
10698        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10699                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10700        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10701        ((WindowManager)mContext.getSystemService(
10702                Context.WINDOW_SERVICE)).addView(v, lp);
10703    }
10704
10705    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10706        if (!(sender instanceof PendingIntentRecord)) {
10707            return;
10708        }
10709        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10710        synchronized (stats) {
10711            if (mBatteryStatsService.isOnBattery()) {
10712                mBatteryStatsService.enforceCallingPermission();
10713                PendingIntentRecord rec = (PendingIntentRecord)sender;
10714                int MY_UID = Binder.getCallingUid();
10715                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10716                BatteryStatsImpl.Uid.Pkg pkg =
10717                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10718                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10719                pkg.incWakeupsLocked();
10720            }
10721        }
10722    }
10723
10724    public boolean killPids(int[] pids, String pReason, boolean secure) {
10725        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10726            throw new SecurityException("killPids only available to the system");
10727        }
10728        String reason = (pReason == null) ? "Unknown" : pReason;
10729        // XXX Note: don't acquire main activity lock here, because the window
10730        // manager calls in with its locks held.
10731
10732        boolean killed = false;
10733        synchronized (mPidsSelfLocked) {
10734            int[] types = new int[pids.length];
10735            int worstType = 0;
10736            for (int i=0; i<pids.length; i++) {
10737                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10738                if (proc != null) {
10739                    int type = proc.setAdj;
10740                    types[i] = type;
10741                    if (type > worstType) {
10742                        worstType = type;
10743                    }
10744                }
10745            }
10746
10747            // If the worst oom_adj is somewhere in the cached proc LRU range,
10748            // then constrain it so we will kill all cached procs.
10749            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10750                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10751                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10752            }
10753
10754            // If this is not a secure call, don't let it kill processes that
10755            // are important.
10756            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10757                worstType = ProcessList.SERVICE_ADJ;
10758            }
10759
10760            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10761            for (int i=0; i<pids.length; i++) {
10762                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10763                if (proc == null) {
10764                    continue;
10765                }
10766                int adj = proc.setAdj;
10767                if (adj >= worstType && !proc.killedByAm) {
10768                    proc.kill(reason, true);
10769                    killed = true;
10770                }
10771            }
10772        }
10773        return killed;
10774    }
10775
10776    @Override
10777    public void killUid(int uid, String reason) {
10778        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10779            throw new SecurityException("killUid only available to the system");
10780        }
10781        synchronized (this) {
10782            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10783                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10784                    reason != null ? reason : "kill uid");
10785        }
10786    }
10787
10788    @Override
10789    public boolean killProcessesBelowForeground(String reason) {
10790        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10791            throw new SecurityException("killProcessesBelowForeground() only available to system");
10792        }
10793
10794        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10795    }
10796
10797    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10798        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10799            throw new SecurityException("killProcessesBelowAdj() only available to system");
10800        }
10801
10802        boolean killed = false;
10803        synchronized (mPidsSelfLocked) {
10804            final int size = mPidsSelfLocked.size();
10805            for (int i = 0; i < size; i++) {
10806                final int pid = mPidsSelfLocked.keyAt(i);
10807                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10808                if (proc == null) continue;
10809
10810                final int adj = proc.setAdj;
10811                if (adj > belowAdj && !proc.killedByAm) {
10812                    proc.kill(reason, true);
10813                    killed = true;
10814                }
10815            }
10816        }
10817        return killed;
10818    }
10819
10820    @Override
10821    public void hang(final IBinder who, boolean allowRestart) {
10822        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10823                != PackageManager.PERMISSION_GRANTED) {
10824            throw new SecurityException("Requires permission "
10825                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10826        }
10827
10828        final IBinder.DeathRecipient death = new DeathRecipient() {
10829            @Override
10830            public void binderDied() {
10831                synchronized (this) {
10832                    notifyAll();
10833                }
10834            }
10835        };
10836
10837        try {
10838            who.linkToDeath(death, 0);
10839        } catch (RemoteException e) {
10840            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10841            return;
10842        }
10843
10844        synchronized (this) {
10845            Watchdog.getInstance().setAllowRestart(allowRestart);
10846            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10847            synchronized (death) {
10848                while (who.isBinderAlive()) {
10849                    try {
10850                        death.wait();
10851                    } catch (InterruptedException e) {
10852                    }
10853                }
10854            }
10855            Watchdog.getInstance().setAllowRestart(true);
10856        }
10857    }
10858
10859    @Override
10860    public void restart() {
10861        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10862                != PackageManager.PERMISSION_GRANTED) {
10863            throw new SecurityException("Requires permission "
10864                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10865        }
10866
10867        Log.i(TAG, "Sending shutdown broadcast...");
10868
10869        BroadcastReceiver br = new BroadcastReceiver() {
10870            @Override public void onReceive(Context context, Intent intent) {
10871                // Now the broadcast is done, finish up the low-level shutdown.
10872                Log.i(TAG, "Shutting down activity manager...");
10873                shutdown(10000);
10874                Log.i(TAG, "Shutdown complete, restarting!");
10875                Process.killProcess(Process.myPid());
10876                System.exit(10);
10877            }
10878        };
10879
10880        // First send the high-level shut down broadcast.
10881        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10882        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10883        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10884        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10885        mContext.sendOrderedBroadcastAsUser(intent,
10886                UserHandle.ALL, null, br, mHandler, 0, null, null);
10887        */
10888        br.onReceive(mContext, intent);
10889    }
10890
10891    private long getLowRamTimeSinceIdle(long now) {
10892        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10893    }
10894
10895    @Override
10896    public void performIdleMaintenance() {
10897        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10898                != PackageManager.PERMISSION_GRANTED) {
10899            throw new SecurityException("Requires permission "
10900                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10901        }
10902
10903        synchronized (this) {
10904            final long now = SystemClock.uptimeMillis();
10905            final long timeSinceLastIdle = now - mLastIdleTime;
10906            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10907            mLastIdleTime = now;
10908            mLowRamTimeSinceLastIdle = 0;
10909            if (mLowRamStartTime != 0) {
10910                mLowRamStartTime = now;
10911            }
10912
10913            StringBuilder sb = new StringBuilder(128);
10914            sb.append("Idle maintenance over ");
10915            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10916            sb.append(" low RAM for ");
10917            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10918            Slog.i(TAG, sb.toString());
10919
10920            // If at least 1/3 of our time since the last idle period has been spent
10921            // with RAM low, then we want to kill processes.
10922            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10923
10924            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10925                ProcessRecord proc = mLruProcesses.get(i);
10926                if (proc.notCachedSinceIdle) {
10927                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10928                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10929                        if (doKilling && proc.initialIdlePss != 0
10930                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10931                            sb = new StringBuilder(128);
10932                            sb.append("Kill");
10933                            sb.append(proc.processName);
10934                            sb.append(" in idle maint: pss=");
10935                            sb.append(proc.lastPss);
10936                            sb.append(", initialPss=");
10937                            sb.append(proc.initialIdlePss);
10938                            sb.append(", period=");
10939                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10940                            sb.append(", lowRamPeriod=");
10941                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10942                            Slog.wtfQuiet(TAG, sb.toString());
10943                            proc.kill("idle maint (pss " + proc.lastPss
10944                                    + " from " + proc.initialIdlePss + ")", true);
10945                        }
10946                    }
10947                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10948                    proc.notCachedSinceIdle = true;
10949                    proc.initialIdlePss = 0;
10950                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10951                            mTestPssMode, isSleeping(), now);
10952                }
10953            }
10954
10955            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10956            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10957        }
10958    }
10959
10960    private void retrieveSettings() {
10961        final ContentResolver resolver = mContext.getContentResolver();
10962        String debugApp = Settings.Global.getString(
10963            resolver, Settings.Global.DEBUG_APP);
10964        boolean waitForDebugger = Settings.Global.getInt(
10965            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10966        boolean alwaysFinishActivities = Settings.Global.getInt(
10967            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10968        boolean forceRtl = Settings.Global.getInt(
10969                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10970        // Transfer any global setting for forcing RTL layout, into a System Property
10971        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10972
10973        Configuration configuration = new Configuration();
10974        Settings.System.getConfiguration(resolver, configuration);
10975        if (forceRtl) {
10976            // This will take care of setting the correct layout direction flags
10977            configuration.setLayoutDirection(configuration.locale);
10978        }
10979
10980        synchronized (this) {
10981            mDebugApp = mOrigDebugApp = debugApp;
10982            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10983            mAlwaysFinishActivities = alwaysFinishActivities;
10984            // This happens before any activities are started, so we can
10985            // change mConfiguration in-place.
10986            updateConfigurationLocked(configuration, null, false, true);
10987            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10988        }
10989    }
10990
10991    /** Loads resources after the current configuration has been set. */
10992    private void loadResourcesOnSystemReady() {
10993        final Resources res = mContext.getResources();
10994        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10995        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10996        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10997    }
10998
10999    public boolean testIsSystemReady() {
11000        // no need to synchronize(this) just to read & return the value
11001        return mSystemReady;
11002    }
11003
11004    private static File getCalledPreBootReceiversFile() {
11005        File dataDir = Environment.getDataDirectory();
11006        File systemDir = new File(dataDir, "system");
11007        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11008        return fname;
11009    }
11010
11011    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11012        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11013        File file = getCalledPreBootReceiversFile();
11014        FileInputStream fis = null;
11015        try {
11016            fis = new FileInputStream(file);
11017            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11018            int fvers = dis.readInt();
11019            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11020                String vers = dis.readUTF();
11021                String codename = dis.readUTF();
11022                String build = dis.readUTF();
11023                if (android.os.Build.VERSION.RELEASE.equals(vers)
11024                        && android.os.Build.VERSION.CODENAME.equals(codename)
11025                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11026                    int num = dis.readInt();
11027                    while (num > 0) {
11028                        num--;
11029                        String pkg = dis.readUTF();
11030                        String cls = dis.readUTF();
11031                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11032                    }
11033                }
11034            }
11035        } catch (FileNotFoundException e) {
11036        } catch (IOException e) {
11037            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11038        } finally {
11039            if (fis != null) {
11040                try {
11041                    fis.close();
11042                } catch (IOException e) {
11043                }
11044            }
11045        }
11046        return lastDoneReceivers;
11047    }
11048
11049    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11050        File file = getCalledPreBootReceiversFile();
11051        FileOutputStream fos = null;
11052        DataOutputStream dos = null;
11053        try {
11054            fos = new FileOutputStream(file);
11055            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11056            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11057            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11058            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11059            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11060            dos.writeInt(list.size());
11061            for (int i=0; i<list.size(); i++) {
11062                dos.writeUTF(list.get(i).getPackageName());
11063                dos.writeUTF(list.get(i).getClassName());
11064            }
11065        } catch (IOException e) {
11066            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11067            file.delete();
11068        } finally {
11069            FileUtils.sync(fos);
11070            if (dos != null) {
11071                try {
11072                    dos.close();
11073                } catch (IOException e) {
11074                    // TODO Auto-generated catch block
11075                    e.printStackTrace();
11076                }
11077            }
11078        }
11079    }
11080
11081    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11082            ArrayList<ComponentName> doneReceivers, int userId) {
11083        boolean waitingUpdate = false;
11084        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11085        List<ResolveInfo> ris = null;
11086        try {
11087            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11088                    intent, null, 0, userId);
11089        } catch (RemoteException e) {
11090        }
11091        if (ris != null) {
11092            for (int i=ris.size()-1; i>=0; i--) {
11093                if ((ris.get(i).activityInfo.applicationInfo.flags
11094                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11095                    ris.remove(i);
11096                }
11097            }
11098            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11099
11100            // For User 0, load the version number. When delivering to a new user, deliver
11101            // to all receivers.
11102            if (userId == UserHandle.USER_OWNER) {
11103                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11104                for (int i=0; i<ris.size(); i++) {
11105                    ActivityInfo ai = ris.get(i).activityInfo;
11106                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11107                    if (lastDoneReceivers.contains(comp)) {
11108                        // We already did the pre boot receiver for this app with the current
11109                        // platform version, so don't do it again...
11110                        ris.remove(i);
11111                        i--;
11112                        // ...however, do keep it as one that has been done, so we don't
11113                        // forget about it when rewriting the file of last done receivers.
11114                        doneReceivers.add(comp);
11115                    }
11116                }
11117            }
11118
11119            // If primary user, send broadcast to all available users, else just to userId
11120            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11121                    : new int[] { userId };
11122            for (int i = 0; i < ris.size(); i++) {
11123                ActivityInfo ai = ris.get(i).activityInfo;
11124                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11125                doneReceivers.add(comp);
11126                intent.setComponent(comp);
11127                for (int j=0; j<users.length; j++) {
11128                    IIntentReceiver finisher = null;
11129                    // On last receiver and user, set up a completion callback
11130                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11131                        finisher = new IIntentReceiver.Stub() {
11132                            public void performReceive(Intent intent, int resultCode,
11133                                    String data, Bundle extras, boolean ordered,
11134                                    boolean sticky, int sendingUser) {
11135                                // The raw IIntentReceiver interface is called
11136                                // with the AM lock held, so redispatch to
11137                                // execute our code without the lock.
11138                                mHandler.post(onFinishCallback);
11139                            }
11140                        };
11141                    }
11142                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11143                            + " for user " + users[j]);
11144                    broadcastIntentLocked(null, null, intent, null, finisher,
11145                            0, null, null, null, AppOpsManager.OP_NONE,
11146                            true, false, MY_PID, Process.SYSTEM_UID,
11147                            users[j]);
11148                    if (finisher != null) {
11149                        waitingUpdate = true;
11150                    }
11151                }
11152            }
11153        }
11154
11155        return waitingUpdate;
11156    }
11157
11158    public void systemReady(final Runnable goingCallback) {
11159        synchronized(this) {
11160            if (mSystemReady) {
11161                // If we're done calling all the receivers, run the next "boot phase" passed in
11162                // by the SystemServer
11163                if (goingCallback != null) {
11164                    goingCallback.run();
11165                }
11166                return;
11167            }
11168
11169            // Make sure we have the current profile info, since it is needed for
11170            // security checks.
11171            updateCurrentProfileIdsLocked();
11172
11173            if (mRecentTasks == null) {
11174                mRecentTasks = mTaskPersister.restoreTasksLocked();
11175                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11176                if (!mRecentTasks.isEmpty()) {
11177                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11178                }
11179                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11180                mTaskPersister.startPersisting();
11181            }
11182
11183            // Check to see if there are any update receivers to run.
11184            if (!mDidUpdate) {
11185                if (mWaitingUpdate) {
11186                    return;
11187                }
11188                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11189                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11190                    public void run() {
11191                        synchronized (ActivityManagerService.this) {
11192                            mDidUpdate = true;
11193                        }
11194                        writeLastDonePreBootReceivers(doneReceivers);
11195                        showBootMessage(mContext.getText(
11196                                R.string.android_upgrading_complete),
11197                                false);
11198                        systemReady(goingCallback);
11199                    }
11200                }, doneReceivers, UserHandle.USER_OWNER);
11201
11202                if (mWaitingUpdate) {
11203                    return;
11204                }
11205                mDidUpdate = true;
11206            }
11207
11208            mAppOpsService.systemReady();
11209            mSystemReady = true;
11210        }
11211
11212        ArrayList<ProcessRecord> procsToKill = null;
11213        synchronized(mPidsSelfLocked) {
11214            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11215                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11216                if (!isAllowedWhileBooting(proc.info)){
11217                    if (procsToKill == null) {
11218                        procsToKill = new ArrayList<ProcessRecord>();
11219                    }
11220                    procsToKill.add(proc);
11221                }
11222            }
11223        }
11224
11225        synchronized(this) {
11226            if (procsToKill != null) {
11227                for (int i=procsToKill.size()-1; i>=0; i--) {
11228                    ProcessRecord proc = procsToKill.get(i);
11229                    Slog.i(TAG, "Removing system update proc: " + proc);
11230                    removeProcessLocked(proc, true, false, "system update done");
11231                }
11232            }
11233
11234            // Now that we have cleaned up any update processes, we
11235            // are ready to start launching real processes and know that
11236            // we won't trample on them any more.
11237            mProcessesReady = true;
11238        }
11239
11240        Slog.i(TAG, "System now ready");
11241        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11242            SystemClock.uptimeMillis());
11243
11244        synchronized(this) {
11245            // Make sure we have no pre-ready processes sitting around.
11246
11247            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11248                ResolveInfo ri = mContext.getPackageManager()
11249                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11250                                STOCK_PM_FLAGS);
11251                CharSequence errorMsg = null;
11252                if (ri != null) {
11253                    ActivityInfo ai = ri.activityInfo;
11254                    ApplicationInfo app = ai.applicationInfo;
11255                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11256                        mTopAction = Intent.ACTION_FACTORY_TEST;
11257                        mTopData = null;
11258                        mTopComponent = new ComponentName(app.packageName,
11259                                ai.name);
11260                    } else {
11261                        errorMsg = mContext.getResources().getText(
11262                                com.android.internal.R.string.factorytest_not_system);
11263                    }
11264                } else {
11265                    errorMsg = mContext.getResources().getText(
11266                            com.android.internal.R.string.factorytest_no_action);
11267                }
11268                if (errorMsg != null) {
11269                    mTopAction = null;
11270                    mTopData = null;
11271                    mTopComponent = null;
11272                    Message msg = Message.obtain();
11273                    msg.what = SHOW_FACTORY_ERROR_MSG;
11274                    msg.getData().putCharSequence("msg", errorMsg);
11275                    mHandler.sendMessage(msg);
11276                }
11277            }
11278        }
11279
11280        retrieveSettings();
11281        loadResourcesOnSystemReady();
11282
11283        synchronized (this) {
11284            readGrantedUriPermissionsLocked();
11285        }
11286
11287        if (goingCallback != null) goingCallback.run();
11288
11289        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11290                Integer.toString(mCurrentUserId), mCurrentUserId);
11291        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11292                Integer.toString(mCurrentUserId), mCurrentUserId);
11293        mSystemServiceManager.startUser(mCurrentUserId);
11294
11295        synchronized (this) {
11296            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11297                try {
11298                    List apps = AppGlobals.getPackageManager().
11299                        getPersistentApplications(STOCK_PM_FLAGS);
11300                    if (apps != null) {
11301                        int N = apps.size();
11302                        int i;
11303                        for (i=0; i<N; i++) {
11304                            ApplicationInfo info
11305                                = (ApplicationInfo)apps.get(i);
11306                            if (info != null &&
11307                                    !info.packageName.equals("android")) {
11308                                addAppLocked(info, false, null /* ABI override */);
11309                            }
11310                        }
11311                    }
11312                } catch (RemoteException ex) {
11313                    // pm is in same process, this will never happen.
11314                }
11315            }
11316
11317            // Start up initial activity.
11318            mBooting = true;
11319            startHomeActivityLocked(mCurrentUserId);
11320
11321            try {
11322                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11323                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11324                            + " data partition or your device will be unstable.");
11325                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11326                }
11327            } catch (RemoteException e) {
11328            }
11329
11330            if (!Build.isFingerprintConsistent()) {
11331                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11332                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11333            }
11334
11335            long ident = Binder.clearCallingIdentity();
11336            try {
11337                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11338                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11339                        | Intent.FLAG_RECEIVER_FOREGROUND);
11340                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11341                broadcastIntentLocked(null, null, intent,
11342                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11343                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11344                intent = new Intent(Intent.ACTION_USER_STARTING);
11345                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11346                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11347                broadcastIntentLocked(null, null, intent,
11348                        null, new IIntentReceiver.Stub() {
11349                            @Override
11350                            public void performReceive(Intent intent, int resultCode, String data,
11351                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11352                                    throws RemoteException {
11353                            }
11354                        }, 0, null, null,
11355                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11356                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11357            } catch (Throwable t) {
11358                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11359            } finally {
11360                Binder.restoreCallingIdentity(ident);
11361            }
11362            mStackSupervisor.resumeTopActivitiesLocked();
11363            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11364        }
11365    }
11366
11367    private boolean makeAppCrashingLocked(ProcessRecord app,
11368            String shortMsg, String longMsg, String stackTrace) {
11369        app.crashing = true;
11370        app.crashingReport = generateProcessError(app,
11371                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11372        startAppProblemLocked(app);
11373        app.stopFreezingAllLocked();
11374        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11375    }
11376
11377    private void makeAppNotRespondingLocked(ProcessRecord app,
11378            String activity, String shortMsg, String longMsg) {
11379        app.notResponding = true;
11380        app.notRespondingReport = generateProcessError(app,
11381                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11382                activity, shortMsg, longMsg, null);
11383        startAppProblemLocked(app);
11384        app.stopFreezingAllLocked();
11385    }
11386
11387    /**
11388     * Generate a process error record, suitable for attachment to a ProcessRecord.
11389     *
11390     * @param app The ProcessRecord in which the error occurred.
11391     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11392     *                      ActivityManager.AppErrorStateInfo
11393     * @param activity The activity associated with the crash, if known.
11394     * @param shortMsg Short message describing the crash.
11395     * @param longMsg Long message describing the crash.
11396     * @param stackTrace Full crash stack trace, may be null.
11397     *
11398     * @return Returns a fully-formed AppErrorStateInfo record.
11399     */
11400    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11401            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11402        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11403
11404        report.condition = condition;
11405        report.processName = app.processName;
11406        report.pid = app.pid;
11407        report.uid = app.info.uid;
11408        report.tag = activity;
11409        report.shortMsg = shortMsg;
11410        report.longMsg = longMsg;
11411        report.stackTrace = stackTrace;
11412
11413        return report;
11414    }
11415
11416    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11417        synchronized (this) {
11418            app.crashing = false;
11419            app.crashingReport = null;
11420            app.notResponding = false;
11421            app.notRespondingReport = null;
11422            if (app.anrDialog == fromDialog) {
11423                app.anrDialog = null;
11424            }
11425            if (app.waitDialog == fromDialog) {
11426                app.waitDialog = null;
11427            }
11428            if (app.pid > 0 && app.pid != MY_PID) {
11429                handleAppCrashLocked(app, null, null, null);
11430                app.kill("user request after error", true);
11431            }
11432        }
11433    }
11434
11435    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11436            String stackTrace) {
11437        long now = SystemClock.uptimeMillis();
11438
11439        Long crashTime;
11440        if (!app.isolated) {
11441            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11442        } else {
11443            crashTime = null;
11444        }
11445        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11446            // This process loses!
11447            Slog.w(TAG, "Process " + app.info.processName
11448                    + " has crashed too many times: killing!");
11449            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11450                    app.userId, app.info.processName, app.uid);
11451            mStackSupervisor.handleAppCrashLocked(app);
11452            if (!app.persistent) {
11453                // We don't want to start this process again until the user
11454                // explicitly does so...  but for persistent process, we really
11455                // need to keep it running.  If a persistent process is actually
11456                // repeatedly crashing, then badness for everyone.
11457                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11458                        app.info.processName);
11459                if (!app.isolated) {
11460                    // XXX We don't have a way to mark isolated processes
11461                    // as bad, since they don't have a peristent identity.
11462                    mBadProcesses.put(app.info.processName, app.uid,
11463                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11464                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11465                }
11466                app.bad = true;
11467                app.removed = true;
11468                // Don't let services in this process be restarted and potentially
11469                // annoy the user repeatedly.  Unless it is persistent, since those
11470                // processes run critical code.
11471                removeProcessLocked(app, false, false, "crash");
11472                mStackSupervisor.resumeTopActivitiesLocked();
11473                return false;
11474            }
11475            mStackSupervisor.resumeTopActivitiesLocked();
11476        } else {
11477            mStackSupervisor.finishTopRunningActivityLocked(app);
11478        }
11479
11480        // Bump up the crash count of any services currently running in the proc.
11481        for (int i=app.services.size()-1; i>=0; i--) {
11482            // Any services running in the application need to be placed
11483            // back in the pending list.
11484            ServiceRecord sr = app.services.valueAt(i);
11485            sr.crashCount++;
11486        }
11487
11488        // If the crashing process is what we consider to be the "home process" and it has been
11489        // replaced by a third-party app, clear the package preferred activities from packages
11490        // with a home activity running in the process to prevent a repeatedly crashing app
11491        // from blocking the user to manually clear the list.
11492        final ArrayList<ActivityRecord> activities = app.activities;
11493        if (app == mHomeProcess && activities.size() > 0
11494                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11495            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11496                final ActivityRecord r = activities.get(activityNdx);
11497                if (r.isHomeActivity()) {
11498                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11499                    try {
11500                        ActivityThread.getPackageManager()
11501                                .clearPackagePreferredActivities(r.packageName);
11502                    } catch (RemoteException c) {
11503                        // pm is in same process, this will never happen.
11504                    }
11505                }
11506            }
11507        }
11508
11509        if (!app.isolated) {
11510            // XXX Can't keep track of crash times for isolated processes,
11511            // because they don't have a perisistent identity.
11512            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11513        }
11514
11515        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11516        return true;
11517    }
11518
11519    void startAppProblemLocked(ProcessRecord app) {
11520        // If this app is not running under the current user, then we
11521        // can't give it a report button because that would require
11522        // launching the report UI under a different user.
11523        app.errorReportReceiver = null;
11524
11525        for (int userId : mCurrentProfileIds) {
11526            if (app.userId == userId) {
11527                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11528                        mContext, app.info.packageName, app.info.flags);
11529            }
11530        }
11531        skipCurrentReceiverLocked(app);
11532    }
11533
11534    void skipCurrentReceiverLocked(ProcessRecord app) {
11535        for (BroadcastQueue queue : mBroadcastQueues) {
11536            queue.skipCurrentReceiverLocked(app);
11537        }
11538    }
11539
11540    /**
11541     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11542     * The application process will exit immediately after this call returns.
11543     * @param app object of the crashing app, null for the system server
11544     * @param crashInfo describing the exception
11545     */
11546    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11547        ProcessRecord r = findAppProcess(app, "Crash");
11548        final String processName = app == null ? "system_server"
11549                : (r == null ? "unknown" : r.processName);
11550
11551        handleApplicationCrashInner("crash", r, processName, crashInfo);
11552    }
11553
11554    /* Native crash reporting uses this inner version because it needs to be somewhat
11555     * decoupled from the AM-managed cleanup lifecycle
11556     */
11557    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11558            ApplicationErrorReport.CrashInfo crashInfo) {
11559        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11560                UserHandle.getUserId(Binder.getCallingUid()), processName,
11561                r == null ? -1 : r.info.flags,
11562                crashInfo.exceptionClassName,
11563                crashInfo.exceptionMessage,
11564                crashInfo.throwFileName,
11565                crashInfo.throwLineNumber);
11566
11567        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11568
11569        crashApplication(r, crashInfo);
11570    }
11571
11572    public void handleApplicationStrictModeViolation(
11573            IBinder app,
11574            int violationMask,
11575            StrictMode.ViolationInfo info) {
11576        ProcessRecord r = findAppProcess(app, "StrictMode");
11577        if (r == null) {
11578            return;
11579        }
11580
11581        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11582            Integer stackFingerprint = info.hashCode();
11583            boolean logIt = true;
11584            synchronized (mAlreadyLoggedViolatedStacks) {
11585                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11586                    logIt = false;
11587                    // TODO: sub-sample into EventLog for these, with
11588                    // the info.durationMillis?  Then we'd get
11589                    // the relative pain numbers, without logging all
11590                    // the stack traces repeatedly.  We'd want to do
11591                    // likewise in the client code, which also does
11592                    // dup suppression, before the Binder call.
11593                } else {
11594                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11595                        mAlreadyLoggedViolatedStacks.clear();
11596                    }
11597                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11598                }
11599            }
11600            if (logIt) {
11601                logStrictModeViolationToDropBox(r, info);
11602            }
11603        }
11604
11605        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11606            AppErrorResult result = new AppErrorResult();
11607            synchronized (this) {
11608                final long origId = Binder.clearCallingIdentity();
11609
11610                Message msg = Message.obtain();
11611                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11612                HashMap<String, Object> data = new HashMap<String, Object>();
11613                data.put("result", result);
11614                data.put("app", r);
11615                data.put("violationMask", violationMask);
11616                data.put("info", info);
11617                msg.obj = data;
11618                mHandler.sendMessage(msg);
11619
11620                Binder.restoreCallingIdentity(origId);
11621            }
11622            int res = result.get();
11623            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11624        }
11625    }
11626
11627    // Depending on the policy in effect, there could be a bunch of
11628    // these in quick succession so we try to batch these together to
11629    // minimize disk writes, number of dropbox entries, and maximize
11630    // compression, by having more fewer, larger records.
11631    private void logStrictModeViolationToDropBox(
11632            ProcessRecord process,
11633            StrictMode.ViolationInfo info) {
11634        if (info == null) {
11635            return;
11636        }
11637        final boolean isSystemApp = process == null ||
11638                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11639                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11640        final String processName = process == null ? "unknown" : process.processName;
11641        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11642        final DropBoxManager dbox = (DropBoxManager)
11643                mContext.getSystemService(Context.DROPBOX_SERVICE);
11644
11645        // Exit early if the dropbox isn't configured to accept this report type.
11646        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11647
11648        boolean bufferWasEmpty;
11649        boolean needsFlush;
11650        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11651        synchronized (sb) {
11652            bufferWasEmpty = sb.length() == 0;
11653            appendDropBoxProcessHeaders(process, processName, sb);
11654            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11655            sb.append("System-App: ").append(isSystemApp).append("\n");
11656            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11657            if (info.violationNumThisLoop != 0) {
11658                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11659            }
11660            if (info.numAnimationsRunning != 0) {
11661                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11662            }
11663            if (info.broadcastIntentAction != null) {
11664                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11665            }
11666            if (info.durationMillis != -1) {
11667                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11668            }
11669            if (info.numInstances != -1) {
11670                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11671            }
11672            if (info.tags != null) {
11673                for (String tag : info.tags) {
11674                    sb.append("Span-Tag: ").append(tag).append("\n");
11675                }
11676            }
11677            sb.append("\n");
11678            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11679                sb.append(info.crashInfo.stackTrace);
11680            }
11681            sb.append("\n");
11682
11683            // Only buffer up to ~64k.  Various logging bits truncate
11684            // things at 128k.
11685            needsFlush = (sb.length() > 64 * 1024);
11686        }
11687
11688        // Flush immediately if the buffer's grown too large, or this
11689        // is a non-system app.  Non-system apps are isolated with a
11690        // different tag & policy and not batched.
11691        //
11692        // Batching is useful during internal testing with
11693        // StrictMode settings turned up high.  Without batching,
11694        // thousands of separate files could be created on boot.
11695        if (!isSystemApp || needsFlush) {
11696            new Thread("Error dump: " + dropboxTag) {
11697                @Override
11698                public void run() {
11699                    String report;
11700                    synchronized (sb) {
11701                        report = sb.toString();
11702                        sb.delete(0, sb.length());
11703                        sb.trimToSize();
11704                    }
11705                    if (report.length() != 0) {
11706                        dbox.addText(dropboxTag, report);
11707                    }
11708                }
11709            }.start();
11710            return;
11711        }
11712
11713        // System app batching:
11714        if (!bufferWasEmpty) {
11715            // An existing dropbox-writing thread is outstanding, so
11716            // we don't need to start it up.  The existing thread will
11717            // catch the buffer appends we just did.
11718            return;
11719        }
11720
11721        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11722        // (After this point, we shouldn't access AMS internal data structures.)
11723        new Thread("Error dump: " + dropboxTag) {
11724            @Override
11725            public void run() {
11726                // 5 second sleep to let stacks arrive and be batched together
11727                try {
11728                    Thread.sleep(5000);  // 5 seconds
11729                } catch (InterruptedException e) {}
11730
11731                String errorReport;
11732                synchronized (mStrictModeBuffer) {
11733                    errorReport = mStrictModeBuffer.toString();
11734                    if (errorReport.length() == 0) {
11735                        return;
11736                    }
11737                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11738                    mStrictModeBuffer.trimToSize();
11739                }
11740                dbox.addText(dropboxTag, errorReport);
11741            }
11742        }.start();
11743    }
11744
11745    /**
11746     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11747     * @param app object of the crashing app, null for the system server
11748     * @param tag reported by the caller
11749     * @param system whether this wtf is coming from the system
11750     * @param crashInfo describing the context of the error
11751     * @return true if the process should exit immediately (WTF is fatal)
11752     */
11753    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11754            final ApplicationErrorReport.CrashInfo crashInfo) {
11755        final int callingUid = Binder.getCallingUid();
11756        final int callingPid = Binder.getCallingPid();
11757
11758        if (system) {
11759            // If this is coming from the system, we could very well have low-level
11760            // system locks held, so we want to do this all asynchronously.  And we
11761            // never want this to become fatal, so there is that too.
11762            mHandler.post(new Runnable() {
11763                @Override public void run() {
11764                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11765                }
11766            });
11767            return false;
11768        }
11769
11770        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11771                crashInfo);
11772
11773        if (r != null && r.pid != Process.myPid() &&
11774                Settings.Global.getInt(mContext.getContentResolver(),
11775                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11776            crashApplication(r, crashInfo);
11777            return true;
11778        } else {
11779            return false;
11780        }
11781    }
11782
11783    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11784            final ApplicationErrorReport.CrashInfo crashInfo) {
11785        final ProcessRecord r = findAppProcess(app, "WTF");
11786        final String processName = app == null ? "system_server"
11787                : (r == null ? "unknown" : r.processName);
11788
11789        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11790                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11791
11792        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11793
11794        return r;
11795    }
11796
11797    /**
11798     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11799     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11800     */
11801    private ProcessRecord findAppProcess(IBinder app, String reason) {
11802        if (app == null) {
11803            return null;
11804        }
11805
11806        synchronized (this) {
11807            final int NP = mProcessNames.getMap().size();
11808            for (int ip=0; ip<NP; ip++) {
11809                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11810                final int NA = apps.size();
11811                for (int ia=0; ia<NA; ia++) {
11812                    ProcessRecord p = apps.valueAt(ia);
11813                    if (p.thread != null && p.thread.asBinder() == app) {
11814                        return p;
11815                    }
11816                }
11817            }
11818
11819            Slog.w(TAG, "Can't find mystery application for " + reason
11820                    + " from pid=" + Binder.getCallingPid()
11821                    + " uid=" + Binder.getCallingUid() + ": " + app);
11822            return null;
11823        }
11824    }
11825
11826    /**
11827     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11828     * to append various headers to the dropbox log text.
11829     */
11830    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11831            StringBuilder sb) {
11832        // Watchdog thread ends up invoking this function (with
11833        // a null ProcessRecord) to add the stack file to dropbox.
11834        // Do not acquire a lock on this (am) in such cases, as it
11835        // could cause a potential deadlock, if and when watchdog
11836        // is invoked due to unavailability of lock on am and it
11837        // would prevent watchdog from killing system_server.
11838        if (process == null) {
11839            sb.append("Process: ").append(processName).append("\n");
11840            return;
11841        }
11842        // Note: ProcessRecord 'process' is guarded by the service
11843        // instance.  (notably process.pkgList, which could otherwise change
11844        // concurrently during execution of this method)
11845        synchronized (this) {
11846            sb.append("Process: ").append(processName).append("\n");
11847            int flags = process.info.flags;
11848            IPackageManager pm = AppGlobals.getPackageManager();
11849            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11850            for (int ip=0; ip<process.pkgList.size(); ip++) {
11851                String pkg = process.pkgList.keyAt(ip);
11852                sb.append("Package: ").append(pkg);
11853                try {
11854                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11855                    if (pi != null) {
11856                        sb.append(" v").append(pi.versionCode);
11857                        if (pi.versionName != null) {
11858                            sb.append(" (").append(pi.versionName).append(")");
11859                        }
11860                    }
11861                } catch (RemoteException e) {
11862                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11863                }
11864                sb.append("\n");
11865            }
11866        }
11867    }
11868
11869    private static String processClass(ProcessRecord process) {
11870        if (process == null || process.pid == MY_PID) {
11871            return "system_server";
11872        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11873            return "system_app";
11874        } else {
11875            return "data_app";
11876        }
11877    }
11878
11879    /**
11880     * Write a description of an error (crash, WTF, ANR) to the drop box.
11881     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11882     * @param process which caused the error, null means the system server
11883     * @param activity which triggered the error, null if unknown
11884     * @param parent activity related to the error, null if unknown
11885     * @param subject line related to the error, null if absent
11886     * @param report in long form describing the error, null if absent
11887     * @param logFile to include in the report, null if none
11888     * @param crashInfo giving an application stack trace, null if absent
11889     */
11890    public void addErrorToDropBox(String eventType,
11891            ProcessRecord process, String processName, ActivityRecord activity,
11892            ActivityRecord parent, String subject,
11893            final String report, final File logFile,
11894            final ApplicationErrorReport.CrashInfo crashInfo) {
11895        // NOTE -- this must never acquire the ActivityManagerService lock,
11896        // otherwise the watchdog may be prevented from resetting the system.
11897
11898        final String dropboxTag = processClass(process) + "_" + eventType;
11899        final DropBoxManager dbox = (DropBoxManager)
11900                mContext.getSystemService(Context.DROPBOX_SERVICE);
11901
11902        // Exit early if the dropbox isn't configured to accept this report type.
11903        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11904
11905        final StringBuilder sb = new StringBuilder(1024);
11906        appendDropBoxProcessHeaders(process, processName, sb);
11907        if (activity != null) {
11908            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11909        }
11910        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11911            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11912        }
11913        if (parent != null && parent != activity) {
11914            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11915        }
11916        if (subject != null) {
11917            sb.append("Subject: ").append(subject).append("\n");
11918        }
11919        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11920        if (Debug.isDebuggerConnected()) {
11921            sb.append("Debugger: Connected\n");
11922        }
11923        sb.append("\n");
11924
11925        // Do the rest in a worker thread to avoid blocking the caller on I/O
11926        // (After this point, we shouldn't access AMS internal data structures.)
11927        Thread worker = new Thread("Error dump: " + dropboxTag) {
11928            @Override
11929            public void run() {
11930                if (report != null) {
11931                    sb.append(report);
11932                }
11933                if (logFile != null) {
11934                    try {
11935                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11936                                    "\n\n[[TRUNCATED]]"));
11937                    } catch (IOException e) {
11938                        Slog.e(TAG, "Error reading " + logFile, e);
11939                    }
11940                }
11941                if (crashInfo != null && crashInfo.stackTrace != null) {
11942                    sb.append(crashInfo.stackTrace);
11943                }
11944
11945                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11946                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11947                if (lines > 0) {
11948                    sb.append("\n");
11949
11950                    // Merge several logcat streams, and take the last N lines
11951                    InputStreamReader input = null;
11952                    try {
11953                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11954                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11955                                "-b", "crash",
11956                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11957
11958                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11959                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11960                        input = new InputStreamReader(logcat.getInputStream());
11961
11962                        int num;
11963                        char[] buf = new char[8192];
11964                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11965                    } catch (IOException e) {
11966                        Slog.e(TAG, "Error running logcat", e);
11967                    } finally {
11968                        if (input != null) try { input.close(); } catch (IOException e) {}
11969                    }
11970                }
11971
11972                dbox.addText(dropboxTag, sb.toString());
11973            }
11974        };
11975
11976        if (process == null) {
11977            // If process is null, we are being called from some internal code
11978            // and may be about to die -- run this synchronously.
11979            worker.run();
11980        } else {
11981            worker.start();
11982        }
11983    }
11984
11985    /**
11986     * Bring up the "unexpected error" dialog box for a crashing app.
11987     * Deal with edge cases (intercepts from instrumented applications,
11988     * ActivityController, error intent receivers, that sort of thing).
11989     * @param r the application crashing
11990     * @param crashInfo describing the failure
11991     */
11992    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11993        long timeMillis = System.currentTimeMillis();
11994        String shortMsg = crashInfo.exceptionClassName;
11995        String longMsg = crashInfo.exceptionMessage;
11996        String stackTrace = crashInfo.stackTrace;
11997        if (shortMsg != null && longMsg != null) {
11998            longMsg = shortMsg + ": " + longMsg;
11999        } else if (shortMsg != null) {
12000            longMsg = shortMsg;
12001        }
12002
12003        AppErrorResult result = new AppErrorResult();
12004        synchronized (this) {
12005            if (mController != null) {
12006                try {
12007                    String name = r != null ? r.processName : null;
12008                    int pid = r != null ? r.pid : Binder.getCallingPid();
12009                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12010                    if (!mController.appCrashed(name, pid,
12011                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12012                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12013                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12014                            Slog.w(TAG, "Skip killing native crashed app " + name
12015                                    + "(" + pid + ") during testing");
12016                        } else {
12017                            Slog.w(TAG, "Force-killing crashed app " + name
12018                                    + " at watcher's request");
12019                            if (r != null) {
12020                                r.kill("crash", true);
12021                            } else {
12022                                // Huh.
12023                                Process.killProcess(pid);
12024                                Process.killProcessGroup(uid, pid);
12025                            }
12026                        }
12027                        return;
12028                    }
12029                } catch (RemoteException e) {
12030                    mController = null;
12031                    Watchdog.getInstance().setActivityController(null);
12032                }
12033            }
12034
12035            final long origId = Binder.clearCallingIdentity();
12036
12037            // If this process is running instrumentation, finish it.
12038            if (r != null && r.instrumentationClass != null) {
12039                Slog.w(TAG, "Error in app " + r.processName
12040                      + " running instrumentation " + r.instrumentationClass + ":");
12041                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12042                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12043                Bundle info = new Bundle();
12044                info.putString("shortMsg", shortMsg);
12045                info.putString("longMsg", longMsg);
12046                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12047                Binder.restoreCallingIdentity(origId);
12048                return;
12049            }
12050
12051            // Log crash in battery stats.
12052            if (r != null) {
12053                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12054            }
12055
12056            // If we can't identify the process or it's already exceeded its crash quota,
12057            // quit right away without showing a crash dialog.
12058            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12059                Binder.restoreCallingIdentity(origId);
12060                return;
12061            }
12062
12063            Message msg = Message.obtain();
12064            msg.what = SHOW_ERROR_MSG;
12065            HashMap data = new HashMap();
12066            data.put("result", result);
12067            data.put("app", r);
12068            msg.obj = data;
12069            mHandler.sendMessage(msg);
12070
12071            Binder.restoreCallingIdentity(origId);
12072        }
12073
12074        int res = result.get();
12075
12076        Intent appErrorIntent = null;
12077        synchronized (this) {
12078            if (r != null && !r.isolated) {
12079                // XXX Can't keep track of crash time for isolated processes,
12080                // since they don't have a persistent identity.
12081                mProcessCrashTimes.put(r.info.processName, r.uid,
12082                        SystemClock.uptimeMillis());
12083            }
12084            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12085                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12086            }
12087        }
12088
12089        if (appErrorIntent != null) {
12090            try {
12091                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12092            } catch (ActivityNotFoundException e) {
12093                Slog.w(TAG, "bug report receiver dissappeared", e);
12094            }
12095        }
12096    }
12097
12098    Intent createAppErrorIntentLocked(ProcessRecord r,
12099            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12100        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12101        if (report == null) {
12102            return null;
12103        }
12104        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12105        result.setComponent(r.errorReportReceiver);
12106        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12107        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12108        return result;
12109    }
12110
12111    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12112            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12113        if (r.errorReportReceiver == null) {
12114            return null;
12115        }
12116
12117        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12118            return null;
12119        }
12120
12121        ApplicationErrorReport report = new ApplicationErrorReport();
12122        report.packageName = r.info.packageName;
12123        report.installerPackageName = r.errorReportReceiver.getPackageName();
12124        report.processName = r.processName;
12125        report.time = timeMillis;
12126        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12127
12128        if (r.crashing || r.forceCrashReport) {
12129            report.type = ApplicationErrorReport.TYPE_CRASH;
12130            report.crashInfo = crashInfo;
12131        } else if (r.notResponding) {
12132            report.type = ApplicationErrorReport.TYPE_ANR;
12133            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12134
12135            report.anrInfo.activity = r.notRespondingReport.tag;
12136            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12137            report.anrInfo.info = r.notRespondingReport.longMsg;
12138        }
12139
12140        return report;
12141    }
12142
12143    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12144        enforceNotIsolatedCaller("getProcessesInErrorState");
12145        // assume our apps are happy - lazy create the list
12146        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12147
12148        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12149                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12150        int userId = UserHandle.getUserId(Binder.getCallingUid());
12151
12152        synchronized (this) {
12153
12154            // iterate across all processes
12155            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12156                ProcessRecord app = mLruProcesses.get(i);
12157                if (!allUsers && app.userId != userId) {
12158                    continue;
12159                }
12160                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12161                    // This one's in trouble, so we'll generate a report for it
12162                    // crashes are higher priority (in case there's a crash *and* an anr)
12163                    ActivityManager.ProcessErrorStateInfo report = null;
12164                    if (app.crashing) {
12165                        report = app.crashingReport;
12166                    } else if (app.notResponding) {
12167                        report = app.notRespondingReport;
12168                    }
12169
12170                    if (report != null) {
12171                        if (errList == null) {
12172                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12173                        }
12174                        errList.add(report);
12175                    } else {
12176                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12177                                " crashing = " + app.crashing +
12178                                " notResponding = " + app.notResponding);
12179                    }
12180                }
12181            }
12182        }
12183
12184        return errList;
12185    }
12186
12187    static int procStateToImportance(int procState, int memAdj,
12188            ActivityManager.RunningAppProcessInfo currApp) {
12189        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12190        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12191            currApp.lru = memAdj;
12192        } else {
12193            currApp.lru = 0;
12194        }
12195        return imp;
12196    }
12197
12198    private void fillInProcMemInfo(ProcessRecord app,
12199            ActivityManager.RunningAppProcessInfo outInfo) {
12200        outInfo.pid = app.pid;
12201        outInfo.uid = app.info.uid;
12202        if (mHeavyWeightProcess == app) {
12203            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12204        }
12205        if (app.persistent) {
12206            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12207        }
12208        if (app.activities.size() > 0) {
12209            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12210        }
12211        outInfo.lastTrimLevel = app.trimMemoryLevel;
12212        int adj = app.curAdj;
12213        int procState = app.curProcState;
12214        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12215        outInfo.importanceReasonCode = app.adjTypeCode;
12216        outInfo.processState = app.curProcState;
12217    }
12218
12219    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12220        enforceNotIsolatedCaller("getRunningAppProcesses");
12221        // Lazy instantiation of list
12222        List<ActivityManager.RunningAppProcessInfo> runList = null;
12223        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12224                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12225        int userId = UserHandle.getUserId(Binder.getCallingUid());
12226        synchronized (this) {
12227            // Iterate across all processes
12228            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12229                ProcessRecord app = mLruProcesses.get(i);
12230                if (!allUsers && app.userId != userId) {
12231                    continue;
12232                }
12233                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12234                    // Generate process state info for running application
12235                    ActivityManager.RunningAppProcessInfo currApp =
12236                        new ActivityManager.RunningAppProcessInfo(app.processName,
12237                                app.pid, app.getPackageList());
12238                    fillInProcMemInfo(app, currApp);
12239                    if (app.adjSource instanceof ProcessRecord) {
12240                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12241                        currApp.importanceReasonImportance =
12242                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12243                                        app.adjSourceProcState);
12244                    } else if (app.adjSource instanceof ActivityRecord) {
12245                        ActivityRecord r = (ActivityRecord)app.adjSource;
12246                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12247                    }
12248                    if (app.adjTarget instanceof ComponentName) {
12249                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12250                    }
12251                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12252                    //        + " lru=" + currApp.lru);
12253                    if (runList == null) {
12254                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12255                    }
12256                    runList.add(currApp);
12257                }
12258            }
12259        }
12260        return runList;
12261    }
12262
12263    public List<ApplicationInfo> getRunningExternalApplications() {
12264        enforceNotIsolatedCaller("getRunningExternalApplications");
12265        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12266        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12267        if (runningApps != null && runningApps.size() > 0) {
12268            Set<String> extList = new HashSet<String>();
12269            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12270                if (app.pkgList != null) {
12271                    for (String pkg : app.pkgList) {
12272                        extList.add(pkg);
12273                    }
12274                }
12275            }
12276            IPackageManager pm = AppGlobals.getPackageManager();
12277            for (String pkg : extList) {
12278                try {
12279                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12280                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12281                        retList.add(info);
12282                    }
12283                } catch (RemoteException e) {
12284                }
12285            }
12286        }
12287        return retList;
12288    }
12289
12290    @Override
12291    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12292        enforceNotIsolatedCaller("getMyMemoryState");
12293        synchronized (this) {
12294            ProcessRecord proc;
12295            synchronized (mPidsSelfLocked) {
12296                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12297            }
12298            fillInProcMemInfo(proc, outInfo);
12299        }
12300    }
12301
12302    @Override
12303    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12304        if (checkCallingPermission(android.Manifest.permission.DUMP)
12305                != PackageManager.PERMISSION_GRANTED) {
12306            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12307                    + Binder.getCallingPid()
12308                    + ", uid=" + Binder.getCallingUid()
12309                    + " without permission "
12310                    + android.Manifest.permission.DUMP);
12311            return;
12312        }
12313
12314        boolean dumpAll = false;
12315        boolean dumpClient = false;
12316        String dumpPackage = null;
12317
12318        int opti = 0;
12319        while (opti < args.length) {
12320            String opt = args[opti];
12321            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12322                break;
12323            }
12324            opti++;
12325            if ("-a".equals(opt)) {
12326                dumpAll = true;
12327            } else if ("-c".equals(opt)) {
12328                dumpClient = true;
12329            } else if ("-h".equals(opt)) {
12330                pw.println("Activity manager dump options:");
12331                pw.println("  [-a] [-c] [-h] [cmd] ...");
12332                pw.println("  cmd may be one of:");
12333                pw.println("    a[ctivities]: activity stack state");
12334                pw.println("    r[recents]: recent activities state");
12335                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12336                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12337                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12338                pw.println("    o[om]: out of memory management");
12339                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12340                pw.println("    provider [COMP_SPEC]: provider client-side state");
12341                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12342                pw.println("    service [COMP_SPEC]: service client-side state");
12343                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12344                pw.println("    all: dump all activities");
12345                pw.println("    top: dump the top activity");
12346                pw.println("    write: write all pending state to storage");
12347                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12348                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12349                pw.println("    a partial substring in a component name, a");
12350                pw.println("    hex object identifier.");
12351                pw.println("  -a: include all available server state.");
12352                pw.println("  -c: include client state.");
12353                return;
12354            } else {
12355                pw.println("Unknown argument: " + opt + "; use -h for help");
12356            }
12357        }
12358
12359        long origId = Binder.clearCallingIdentity();
12360        boolean more = false;
12361        // Is the caller requesting to dump a particular piece of data?
12362        if (opti < args.length) {
12363            String cmd = args[opti];
12364            opti++;
12365            if ("activities".equals(cmd) || "a".equals(cmd)) {
12366                synchronized (this) {
12367                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12368                }
12369            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12370                synchronized (this) {
12371                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12372                }
12373            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12374                String[] newArgs;
12375                String name;
12376                if (opti >= args.length) {
12377                    name = null;
12378                    newArgs = EMPTY_STRING_ARRAY;
12379                } else {
12380                    name = args[opti];
12381                    opti++;
12382                    newArgs = new String[args.length - opti];
12383                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12384                            args.length - opti);
12385                }
12386                synchronized (this) {
12387                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12388                }
12389            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12390                String[] newArgs;
12391                String name;
12392                if (opti >= args.length) {
12393                    name = null;
12394                    newArgs = EMPTY_STRING_ARRAY;
12395                } else {
12396                    name = args[opti];
12397                    opti++;
12398                    newArgs = new String[args.length - opti];
12399                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12400                            args.length - opti);
12401                }
12402                synchronized (this) {
12403                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12404                }
12405            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12406                String[] newArgs;
12407                String name;
12408                if (opti >= args.length) {
12409                    name = null;
12410                    newArgs = EMPTY_STRING_ARRAY;
12411                } else {
12412                    name = args[opti];
12413                    opti++;
12414                    newArgs = new String[args.length - opti];
12415                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12416                            args.length - opti);
12417                }
12418                synchronized (this) {
12419                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12420                }
12421            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12422                synchronized (this) {
12423                    dumpOomLocked(fd, pw, args, opti, true);
12424                }
12425            } else if ("provider".equals(cmd)) {
12426                String[] newArgs;
12427                String name;
12428                if (opti >= args.length) {
12429                    name = null;
12430                    newArgs = EMPTY_STRING_ARRAY;
12431                } else {
12432                    name = args[opti];
12433                    opti++;
12434                    newArgs = new String[args.length - opti];
12435                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12436                }
12437                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12438                    pw.println("No providers match: " + name);
12439                    pw.println("Use -h for help.");
12440                }
12441            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12442                synchronized (this) {
12443                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12444                }
12445            } else if ("service".equals(cmd)) {
12446                String[] newArgs;
12447                String name;
12448                if (opti >= args.length) {
12449                    name = null;
12450                    newArgs = EMPTY_STRING_ARRAY;
12451                } else {
12452                    name = args[opti];
12453                    opti++;
12454                    newArgs = new String[args.length - opti];
12455                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12456                            args.length - opti);
12457                }
12458                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12459                    pw.println("No services match: " + name);
12460                    pw.println("Use -h for help.");
12461                }
12462            } else if ("package".equals(cmd)) {
12463                String[] newArgs;
12464                if (opti >= args.length) {
12465                    pw.println("package: no package name specified");
12466                    pw.println("Use -h for help.");
12467                } else {
12468                    dumpPackage = args[opti];
12469                    opti++;
12470                    newArgs = new String[args.length - opti];
12471                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12472                            args.length - opti);
12473                    args = newArgs;
12474                    opti = 0;
12475                    more = true;
12476                }
12477            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12478                synchronized (this) {
12479                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12480                }
12481            } else if ("write".equals(cmd)) {
12482                mTaskPersister.flush();
12483                pw.println("All tasks persisted.");
12484                return;
12485            } else {
12486                // Dumping a single activity?
12487                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12488                    pw.println("Bad activity command, or no activities match: " + cmd);
12489                    pw.println("Use -h for help.");
12490                }
12491            }
12492            if (!more) {
12493                Binder.restoreCallingIdentity(origId);
12494                return;
12495            }
12496        }
12497
12498        // No piece of data specified, dump everything.
12499        synchronized (this) {
12500            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12501            pw.println();
12502            if (dumpAll) {
12503                pw.println("-------------------------------------------------------------------------------");
12504            }
12505            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12506            pw.println();
12507            if (dumpAll) {
12508                pw.println("-------------------------------------------------------------------------------");
12509            }
12510            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12511            pw.println();
12512            if (dumpAll) {
12513                pw.println("-------------------------------------------------------------------------------");
12514            }
12515            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12516            pw.println();
12517            if (dumpAll) {
12518                pw.println("-------------------------------------------------------------------------------");
12519            }
12520            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12521            pw.println();
12522            if (dumpAll) {
12523                pw.println("-------------------------------------------------------------------------------");
12524            }
12525            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12526            pw.println();
12527            if (dumpAll) {
12528                pw.println("-------------------------------------------------------------------------------");
12529            }
12530            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12531        }
12532        Binder.restoreCallingIdentity(origId);
12533    }
12534
12535    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12536            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12537        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12538
12539        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12540                dumpPackage);
12541        boolean needSep = printedAnything;
12542
12543        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12544                dumpPackage, needSep, "  mFocusedActivity: ");
12545        if (printed) {
12546            printedAnything = true;
12547            needSep = false;
12548        }
12549
12550        if (dumpPackage == null) {
12551            if (needSep) {
12552                pw.println();
12553            }
12554            needSep = true;
12555            printedAnything = true;
12556            mStackSupervisor.dump(pw, "  ");
12557        }
12558
12559        if (!printedAnything) {
12560            pw.println("  (nothing)");
12561        }
12562    }
12563
12564    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12565            int opti, boolean dumpAll, String dumpPackage) {
12566        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12567
12568        boolean printedAnything = false;
12569
12570        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12571            boolean printedHeader = false;
12572
12573            final int N = mRecentTasks.size();
12574            for (int i=0; i<N; i++) {
12575                TaskRecord tr = mRecentTasks.get(i);
12576                if (dumpPackage != null) {
12577                    if (tr.realActivity == null ||
12578                            !dumpPackage.equals(tr.realActivity)) {
12579                        continue;
12580                    }
12581                }
12582                if (!printedHeader) {
12583                    pw.println("  Recent tasks:");
12584                    printedHeader = true;
12585                    printedAnything = true;
12586                }
12587                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12588                        pw.println(tr);
12589                if (dumpAll) {
12590                    mRecentTasks.get(i).dump(pw, "    ");
12591                }
12592            }
12593        }
12594
12595        if (!printedAnything) {
12596            pw.println("  (nothing)");
12597        }
12598    }
12599
12600    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12601            int opti, boolean dumpAll, String dumpPackage) {
12602        boolean needSep = false;
12603        boolean printedAnything = false;
12604        int numPers = 0;
12605
12606        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12607
12608        if (dumpAll) {
12609            final int NP = mProcessNames.getMap().size();
12610            for (int ip=0; ip<NP; ip++) {
12611                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12612                final int NA = procs.size();
12613                for (int ia=0; ia<NA; ia++) {
12614                    ProcessRecord r = procs.valueAt(ia);
12615                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12616                        continue;
12617                    }
12618                    if (!needSep) {
12619                        pw.println("  All known processes:");
12620                        needSep = true;
12621                        printedAnything = true;
12622                    }
12623                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12624                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12625                        pw.print(" "); pw.println(r);
12626                    r.dump(pw, "    ");
12627                    if (r.persistent) {
12628                        numPers++;
12629                    }
12630                }
12631            }
12632        }
12633
12634        if (mIsolatedProcesses.size() > 0) {
12635            boolean printed = false;
12636            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12637                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12638                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12639                    continue;
12640                }
12641                if (!printed) {
12642                    if (needSep) {
12643                        pw.println();
12644                    }
12645                    pw.println("  Isolated process list (sorted by uid):");
12646                    printedAnything = true;
12647                    printed = true;
12648                    needSep = true;
12649                }
12650                pw.println(String.format("%sIsolated #%2d: %s",
12651                        "    ", i, r.toString()));
12652            }
12653        }
12654
12655        if (mLruProcesses.size() > 0) {
12656            if (needSep) {
12657                pw.println();
12658            }
12659            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12660                    pw.print(" total, non-act at ");
12661                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12662                    pw.print(", non-svc at ");
12663                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12664                    pw.println("):");
12665            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12666            needSep = true;
12667            printedAnything = true;
12668        }
12669
12670        if (dumpAll || dumpPackage != null) {
12671            synchronized (mPidsSelfLocked) {
12672                boolean printed = false;
12673                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12674                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12675                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12676                        continue;
12677                    }
12678                    if (!printed) {
12679                        if (needSep) pw.println();
12680                        needSep = true;
12681                        pw.println("  PID mappings:");
12682                        printed = true;
12683                        printedAnything = true;
12684                    }
12685                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12686                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12687                }
12688            }
12689        }
12690
12691        if (mForegroundProcesses.size() > 0) {
12692            synchronized (mPidsSelfLocked) {
12693                boolean printed = false;
12694                for (int i=0; i<mForegroundProcesses.size(); i++) {
12695                    ProcessRecord r = mPidsSelfLocked.get(
12696                            mForegroundProcesses.valueAt(i).pid);
12697                    if (dumpPackage != null && (r == null
12698                            || !r.pkgList.containsKey(dumpPackage))) {
12699                        continue;
12700                    }
12701                    if (!printed) {
12702                        if (needSep) pw.println();
12703                        needSep = true;
12704                        pw.println("  Foreground Processes:");
12705                        printed = true;
12706                        printedAnything = true;
12707                    }
12708                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12709                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12710                }
12711            }
12712        }
12713
12714        if (mPersistentStartingProcesses.size() > 0) {
12715            if (needSep) pw.println();
12716            needSep = true;
12717            printedAnything = true;
12718            pw.println("  Persisent processes that are starting:");
12719            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12720                    "Starting Norm", "Restarting PERS", dumpPackage);
12721        }
12722
12723        if (mRemovedProcesses.size() > 0) {
12724            if (needSep) pw.println();
12725            needSep = true;
12726            printedAnything = true;
12727            pw.println("  Processes that are being removed:");
12728            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12729                    "Removed Norm", "Removed PERS", dumpPackage);
12730        }
12731
12732        if (mProcessesOnHold.size() > 0) {
12733            if (needSep) pw.println();
12734            needSep = true;
12735            printedAnything = true;
12736            pw.println("  Processes that are on old until the system is ready:");
12737            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12738                    "OnHold Norm", "OnHold PERS", dumpPackage);
12739        }
12740
12741        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12742
12743        if (mProcessCrashTimes.getMap().size() > 0) {
12744            boolean printed = false;
12745            long now = SystemClock.uptimeMillis();
12746            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12747            final int NP = pmap.size();
12748            for (int ip=0; ip<NP; ip++) {
12749                String pname = pmap.keyAt(ip);
12750                SparseArray<Long> uids = pmap.valueAt(ip);
12751                final int N = uids.size();
12752                for (int i=0; i<N; i++) {
12753                    int puid = uids.keyAt(i);
12754                    ProcessRecord r = mProcessNames.get(pname, puid);
12755                    if (dumpPackage != null && (r == null
12756                            || !r.pkgList.containsKey(dumpPackage))) {
12757                        continue;
12758                    }
12759                    if (!printed) {
12760                        if (needSep) pw.println();
12761                        needSep = true;
12762                        pw.println("  Time since processes crashed:");
12763                        printed = true;
12764                        printedAnything = true;
12765                    }
12766                    pw.print("    Process "); pw.print(pname);
12767                            pw.print(" uid "); pw.print(puid);
12768                            pw.print(": last crashed ");
12769                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12770                            pw.println(" ago");
12771                }
12772            }
12773        }
12774
12775        if (mBadProcesses.getMap().size() > 0) {
12776            boolean printed = false;
12777            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12778            final int NP = pmap.size();
12779            for (int ip=0; ip<NP; ip++) {
12780                String pname = pmap.keyAt(ip);
12781                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12782                final int N = uids.size();
12783                for (int i=0; i<N; i++) {
12784                    int puid = uids.keyAt(i);
12785                    ProcessRecord r = mProcessNames.get(pname, puid);
12786                    if (dumpPackage != null && (r == null
12787                            || !r.pkgList.containsKey(dumpPackage))) {
12788                        continue;
12789                    }
12790                    if (!printed) {
12791                        if (needSep) pw.println();
12792                        needSep = true;
12793                        pw.println("  Bad processes:");
12794                        printedAnything = true;
12795                    }
12796                    BadProcessInfo info = uids.valueAt(i);
12797                    pw.print("    Bad process "); pw.print(pname);
12798                            pw.print(" uid "); pw.print(puid);
12799                            pw.print(": crashed at time "); pw.println(info.time);
12800                    if (info.shortMsg != null) {
12801                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12802                    }
12803                    if (info.longMsg != null) {
12804                        pw.print("      Long msg: "); pw.println(info.longMsg);
12805                    }
12806                    if (info.stack != null) {
12807                        pw.println("      Stack:");
12808                        int lastPos = 0;
12809                        for (int pos=0; pos<info.stack.length(); pos++) {
12810                            if (info.stack.charAt(pos) == '\n') {
12811                                pw.print("        ");
12812                                pw.write(info.stack, lastPos, pos-lastPos);
12813                                pw.println();
12814                                lastPos = pos+1;
12815                            }
12816                        }
12817                        if (lastPos < info.stack.length()) {
12818                            pw.print("        ");
12819                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12820                            pw.println();
12821                        }
12822                    }
12823                }
12824            }
12825        }
12826
12827        if (dumpPackage == null) {
12828            pw.println();
12829            needSep = false;
12830            pw.println("  mStartedUsers:");
12831            for (int i=0; i<mStartedUsers.size(); i++) {
12832                UserStartedState uss = mStartedUsers.valueAt(i);
12833                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12834                        pw.print(": "); uss.dump("", pw);
12835            }
12836            pw.print("  mStartedUserArray: [");
12837            for (int i=0; i<mStartedUserArray.length; i++) {
12838                if (i > 0) pw.print(", ");
12839                pw.print(mStartedUserArray[i]);
12840            }
12841            pw.println("]");
12842            pw.print("  mUserLru: [");
12843            for (int i=0; i<mUserLru.size(); i++) {
12844                if (i > 0) pw.print(", ");
12845                pw.print(mUserLru.get(i));
12846            }
12847            pw.println("]");
12848            if (dumpAll) {
12849                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12850            }
12851            synchronized (mUserProfileGroupIdsSelfLocked) {
12852                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12853                    pw.println("  mUserProfileGroupIds:");
12854                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12855                        pw.print("    User #");
12856                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12857                        pw.print(" -> profile #");
12858                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12859                    }
12860                }
12861            }
12862        }
12863        if (mHomeProcess != null && (dumpPackage == null
12864                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12865            if (needSep) {
12866                pw.println();
12867                needSep = false;
12868            }
12869            pw.println("  mHomeProcess: " + mHomeProcess);
12870        }
12871        if (mPreviousProcess != null && (dumpPackage == null
12872                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12873            if (needSep) {
12874                pw.println();
12875                needSep = false;
12876            }
12877            pw.println("  mPreviousProcess: " + mPreviousProcess);
12878        }
12879        if (dumpAll) {
12880            StringBuilder sb = new StringBuilder(128);
12881            sb.append("  mPreviousProcessVisibleTime: ");
12882            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12883            pw.println(sb);
12884        }
12885        if (mHeavyWeightProcess != null && (dumpPackage == null
12886                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12887            if (needSep) {
12888                pw.println();
12889                needSep = false;
12890            }
12891            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12892        }
12893        if (dumpPackage == null) {
12894            pw.println("  mConfiguration: " + mConfiguration);
12895        }
12896        if (dumpAll) {
12897            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12898            if (mCompatModePackages.getPackages().size() > 0) {
12899                boolean printed = false;
12900                for (Map.Entry<String, Integer> entry
12901                        : mCompatModePackages.getPackages().entrySet()) {
12902                    String pkg = entry.getKey();
12903                    int mode = entry.getValue();
12904                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12905                        continue;
12906                    }
12907                    if (!printed) {
12908                        pw.println("  mScreenCompatPackages:");
12909                        printed = true;
12910                    }
12911                    pw.print("    "); pw.print(pkg); pw.print(": ");
12912                            pw.print(mode); pw.println();
12913                }
12914            }
12915        }
12916        if (dumpPackage == null) {
12917            pw.println("  mWakefulness="
12918                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12919            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12920                    + lockScreenShownToString());
12921            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12922                    + " mTestPssMode=" + mTestPssMode);
12923        }
12924        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12925                || mOrigWaitForDebugger) {
12926            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12927                    || dumpPackage.equals(mOrigDebugApp)) {
12928                if (needSep) {
12929                    pw.println();
12930                    needSep = false;
12931                }
12932                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12933                        + " mDebugTransient=" + mDebugTransient
12934                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12935            }
12936        }
12937        if (mOpenGlTraceApp != null) {
12938            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12939                if (needSep) {
12940                    pw.println();
12941                    needSep = false;
12942                }
12943                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12944            }
12945        }
12946        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12947                || mProfileFd != null) {
12948            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12949                if (needSep) {
12950                    pw.println();
12951                    needSep = false;
12952                }
12953                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12954                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12955                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12956                        + mAutoStopProfiler);
12957                pw.println("  mProfileType=" + mProfileType);
12958            }
12959        }
12960        if (dumpPackage == null) {
12961            if (mAlwaysFinishActivities || mController != null) {
12962                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12963                        + " mController=" + mController);
12964            }
12965            if (dumpAll) {
12966                pw.println("  Total persistent processes: " + numPers);
12967                pw.println("  mProcessesReady=" + mProcessesReady
12968                        + " mSystemReady=" + mSystemReady
12969                        + " mBooted=" + mBooted
12970                        + " mFactoryTest=" + mFactoryTest);
12971                pw.println("  mBooting=" + mBooting
12972                        + " mCallFinishBooting=" + mCallFinishBooting
12973                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12974                pw.print("  mLastPowerCheckRealtime=");
12975                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12976                        pw.println("");
12977                pw.print("  mLastPowerCheckUptime=");
12978                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12979                        pw.println("");
12980                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12981                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12982                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12983                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12984                        + " (" + mLruProcesses.size() + " total)"
12985                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12986                        + " mNumServiceProcs=" + mNumServiceProcs
12987                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12988                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12989                        + " mLastMemoryLevel" + mLastMemoryLevel
12990                        + " mLastNumProcesses" + mLastNumProcesses);
12991                long now = SystemClock.uptimeMillis();
12992                pw.print("  mLastIdleTime=");
12993                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12994                        pw.print(" mLowRamSinceLastIdle=");
12995                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12996                        pw.println();
12997            }
12998        }
12999
13000        if (!printedAnything) {
13001            pw.println("  (nothing)");
13002        }
13003    }
13004
13005    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13006            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13007        if (mProcessesToGc.size() > 0) {
13008            boolean printed = false;
13009            long now = SystemClock.uptimeMillis();
13010            for (int i=0; i<mProcessesToGc.size(); i++) {
13011                ProcessRecord proc = mProcessesToGc.get(i);
13012                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13013                    continue;
13014                }
13015                if (!printed) {
13016                    if (needSep) pw.println();
13017                    needSep = true;
13018                    pw.println("  Processes that are waiting to GC:");
13019                    printed = true;
13020                }
13021                pw.print("    Process "); pw.println(proc);
13022                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13023                        pw.print(", last gced=");
13024                        pw.print(now-proc.lastRequestedGc);
13025                        pw.print(" ms ago, last lowMem=");
13026                        pw.print(now-proc.lastLowMemory);
13027                        pw.println(" ms ago");
13028
13029            }
13030        }
13031        return needSep;
13032    }
13033
13034    void printOomLevel(PrintWriter pw, String name, int adj) {
13035        pw.print("    ");
13036        if (adj >= 0) {
13037            pw.print(' ');
13038            if (adj < 10) pw.print(' ');
13039        } else {
13040            if (adj > -10) pw.print(' ');
13041        }
13042        pw.print(adj);
13043        pw.print(": ");
13044        pw.print(name);
13045        pw.print(" (");
13046        pw.print(mProcessList.getMemLevel(adj)/1024);
13047        pw.println(" kB)");
13048    }
13049
13050    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13051            int opti, boolean dumpAll) {
13052        boolean needSep = false;
13053
13054        if (mLruProcesses.size() > 0) {
13055            if (needSep) pw.println();
13056            needSep = true;
13057            pw.println("  OOM levels:");
13058            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13059            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13060            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13061            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13062            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13063            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13064            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13065            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13066            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13067            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13068            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13069            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13070            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13071            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13072
13073            if (needSep) pw.println();
13074            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13075                    pw.print(" total, non-act at ");
13076                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13077                    pw.print(", non-svc at ");
13078                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13079                    pw.println("):");
13080            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13081            needSep = true;
13082        }
13083
13084        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13085
13086        pw.println();
13087        pw.println("  mHomeProcess: " + mHomeProcess);
13088        pw.println("  mPreviousProcess: " + mPreviousProcess);
13089        if (mHeavyWeightProcess != null) {
13090            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13091        }
13092
13093        return true;
13094    }
13095
13096    /**
13097     * There are three ways to call this:
13098     *  - no provider specified: dump all the providers
13099     *  - a flattened component name that matched an existing provider was specified as the
13100     *    first arg: dump that one provider
13101     *  - the first arg isn't the flattened component name of an existing provider:
13102     *    dump all providers whose component contains the first arg as a substring
13103     */
13104    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13105            int opti, boolean dumpAll) {
13106        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13107    }
13108
13109    static class ItemMatcher {
13110        ArrayList<ComponentName> components;
13111        ArrayList<String> strings;
13112        ArrayList<Integer> objects;
13113        boolean all;
13114
13115        ItemMatcher() {
13116            all = true;
13117        }
13118
13119        void build(String name) {
13120            ComponentName componentName = ComponentName.unflattenFromString(name);
13121            if (componentName != null) {
13122                if (components == null) {
13123                    components = new ArrayList<ComponentName>();
13124                }
13125                components.add(componentName);
13126                all = false;
13127            } else {
13128                int objectId = 0;
13129                // Not a '/' separated full component name; maybe an object ID?
13130                try {
13131                    objectId = Integer.parseInt(name, 16);
13132                    if (objects == null) {
13133                        objects = new ArrayList<Integer>();
13134                    }
13135                    objects.add(objectId);
13136                    all = false;
13137                } catch (RuntimeException e) {
13138                    // Not an integer; just do string match.
13139                    if (strings == null) {
13140                        strings = new ArrayList<String>();
13141                    }
13142                    strings.add(name);
13143                    all = false;
13144                }
13145            }
13146        }
13147
13148        int build(String[] args, int opti) {
13149            for (; opti<args.length; opti++) {
13150                String name = args[opti];
13151                if ("--".equals(name)) {
13152                    return opti+1;
13153                }
13154                build(name);
13155            }
13156            return opti;
13157        }
13158
13159        boolean match(Object object, ComponentName comp) {
13160            if (all) {
13161                return true;
13162            }
13163            if (components != null) {
13164                for (int i=0; i<components.size(); i++) {
13165                    if (components.get(i).equals(comp)) {
13166                        return true;
13167                    }
13168                }
13169            }
13170            if (objects != null) {
13171                for (int i=0; i<objects.size(); i++) {
13172                    if (System.identityHashCode(object) == objects.get(i)) {
13173                        return true;
13174                    }
13175                }
13176            }
13177            if (strings != null) {
13178                String flat = comp.flattenToString();
13179                for (int i=0; i<strings.size(); i++) {
13180                    if (flat.contains(strings.get(i))) {
13181                        return true;
13182                    }
13183                }
13184            }
13185            return false;
13186        }
13187    }
13188
13189    /**
13190     * There are three things that cmd can be:
13191     *  - a flattened component name that matches an existing activity
13192     *  - the cmd arg isn't the flattened component name of an existing activity:
13193     *    dump all activity whose component contains the cmd as a substring
13194     *  - A hex number of the ActivityRecord object instance.
13195     */
13196    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13197            int opti, boolean dumpAll) {
13198        ArrayList<ActivityRecord> activities;
13199
13200        synchronized (this) {
13201            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13202        }
13203
13204        if (activities.size() <= 0) {
13205            return false;
13206        }
13207
13208        String[] newArgs = new String[args.length - opti];
13209        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13210
13211        TaskRecord lastTask = null;
13212        boolean needSep = false;
13213        for (int i=activities.size()-1; i>=0; i--) {
13214            ActivityRecord r = activities.get(i);
13215            if (needSep) {
13216                pw.println();
13217            }
13218            needSep = true;
13219            synchronized (this) {
13220                if (lastTask != r.task) {
13221                    lastTask = r.task;
13222                    pw.print("TASK "); pw.print(lastTask.affinity);
13223                            pw.print(" id="); pw.println(lastTask.taskId);
13224                    if (dumpAll) {
13225                        lastTask.dump(pw, "  ");
13226                    }
13227                }
13228            }
13229            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13230        }
13231        return true;
13232    }
13233
13234    /**
13235     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13236     * there is a thread associated with the activity.
13237     */
13238    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13239            final ActivityRecord r, String[] args, boolean dumpAll) {
13240        String innerPrefix = prefix + "  ";
13241        synchronized (this) {
13242            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13243                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13244                    pw.print(" pid=");
13245                    if (r.app != null) pw.println(r.app.pid);
13246                    else pw.println("(not running)");
13247            if (dumpAll) {
13248                r.dump(pw, innerPrefix);
13249            }
13250        }
13251        if (r.app != null && r.app.thread != null) {
13252            // flush anything that is already in the PrintWriter since the thread is going
13253            // to write to the file descriptor directly
13254            pw.flush();
13255            try {
13256                TransferPipe tp = new TransferPipe();
13257                try {
13258                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13259                            r.appToken, innerPrefix, args);
13260                    tp.go(fd);
13261                } finally {
13262                    tp.kill();
13263                }
13264            } catch (IOException e) {
13265                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13266            } catch (RemoteException e) {
13267                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13268            }
13269        }
13270    }
13271
13272    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13273            int opti, boolean dumpAll, String dumpPackage) {
13274        boolean needSep = false;
13275        boolean onlyHistory = false;
13276        boolean printedAnything = false;
13277
13278        if ("history".equals(dumpPackage)) {
13279            if (opti < args.length && "-s".equals(args[opti])) {
13280                dumpAll = false;
13281            }
13282            onlyHistory = true;
13283            dumpPackage = null;
13284        }
13285
13286        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13287        if (!onlyHistory && dumpAll) {
13288            if (mRegisteredReceivers.size() > 0) {
13289                boolean printed = false;
13290                Iterator it = mRegisteredReceivers.values().iterator();
13291                while (it.hasNext()) {
13292                    ReceiverList r = (ReceiverList)it.next();
13293                    if (dumpPackage != null && (r.app == null ||
13294                            !dumpPackage.equals(r.app.info.packageName))) {
13295                        continue;
13296                    }
13297                    if (!printed) {
13298                        pw.println("  Registered Receivers:");
13299                        needSep = true;
13300                        printed = true;
13301                        printedAnything = true;
13302                    }
13303                    pw.print("  * "); pw.println(r);
13304                    r.dump(pw, "    ");
13305                }
13306            }
13307
13308            if (mReceiverResolver.dump(pw, needSep ?
13309                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13310                    "    ", dumpPackage, false, false)) {
13311                needSep = true;
13312                printedAnything = true;
13313            }
13314        }
13315
13316        for (BroadcastQueue q : mBroadcastQueues) {
13317            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13318            printedAnything |= needSep;
13319        }
13320
13321        needSep = true;
13322
13323        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13324            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13325                if (needSep) {
13326                    pw.println();
13327                }
13328                needSep = true;
13329                printedAnything = true;
13330                pw.print("  Sticky broadcasts for user ");
13331                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13332                StringBuilder sb = new StringBuilder(128);
13333                for (Map.Entry<String, ArrayList<Intent>> ent
13334                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13335                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13336                    if (dumpAll) {
13337                        pw.println(":");
13338                        ArrayList<Intent> intents = ent.getValue();
13339                        final int N = intents.size();
13340                        for (int i=0; i<N; i++) {
13341                            sb.setLength(0);
13342                            sb.append("    Intent: ");
13343                            intents.get(i).toShortString(sb, false, true, false, false);
13344                            pw.println(sb.toString());
13345                            Bundle bundle = intents.get(i).getExtras();
13346                            if (bundle != null) {
13347                                pw.print("      ");
13348                                pw.println(bundle.toString());
13349                            }
13350                        }
13351                    } else {
13352                        pw.println("");
13353                    }
13354                }
13355            }
13356        }
13357
13358        if (!onlyHistory && dumpAll) {
13359            pw.println();
13360            for (BroadcastQueue queue : mBroadcastQueues) {
13361                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13362                        + queue.mBroadcastsScheduled);
13363            }
13364            pw.println("  mHandler:");
13365            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13366            needSep = true;
13367            printedAnything = true;
13368        }
13369
13370        if (!printedAnything) {
13371            pw.println("  (nothing)");
13372        }
13373    }
13374
13375    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13376            int opti, boolean dumpAll, String dumpPackage) {
13377        boolean needSep;
13378        boolean printedAnything = false;
13379
13380        ItemMatcher matcher = new ItemMatcher();
13381        matcher.build(args, opti);
13382
13383        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13384
13385        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13386        printedAnything |= needSep;
13387
13388        if (mLaunchingProviders.size() > 0) {
13389            boolean printed = false;
13390            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13391                ContentProviderRecord r = mLaunchingProviders.get(i);
13392                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13393                    continue;
13394                }
13395                if (!printed) {
13396                    if (needSep) pw.println();
13397                    needSep = true;
13398                    pw.println("  Launching content providers:");
13399                    printed = true;
13400                    printedAnything = true;
13401                }
13402                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13403                        pw.println(r);
13404            }
13405        }
13406
13407        if (mGrantedUriPermissions.size() > 0) {
13408            boolean printed = false;
13409            int dumpUid = -2;
13410            if (dumpPackage != null) {
13411                try {
13412                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13413                } catch (NameNotFoundException e) {
13414                    dumpUid = -1;
13415                }
13416            }
13417            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13418                int uid = mGrantedUriPermissions.keyAt(i);
13419                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13420                    continue;
13421                }
13422                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13423                if (!printed) {
13424                    if (needSep) pw.println();
13425                    needSep = true;
13426                    pw.println("  Granted Uri Permissions:");
13427                    printed = true;
13428                    printedAnything = true;
13429                }
13430                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13431                for (UriPermission perm : perms.values()) {
13432                    pw.print("    "); pw.println(perm);
13433                    if (dumpAll) {
13434                        perm.dump(pw, "      ");
13435                    }
13436                }
13437            }
13438        }
13439
13440        if (!printedAnything) {
13441            pw.println("  (nothing)");
13442        }
13443    }
13444
13445    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13446            int opti, boolean dumpAll, String dumpPackage) {
13447        boolean printed = false;
13448
13449        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13450
13451        if (mIntentSenderRecords.size() > 0) {
13452            Iterator<WeakReference<PendingIntentRecord>> it
13453                    = mIntentSenderRecords.values().iterator();
13454            while (it.hasNext()) {
13455                WeakReference<PendingIntentRecord> ref = it.next();
13456                PendingIntentRecord rec = ref != null ? ref.get(): null;
13457                if (dumpPackage != null && (rec == null
13458                        || !dumpPackage.equals(rec.key.packageName))) {
13459                    continue;
13460                }
13461                printed = true;
13462                if (rec != null) {
13463                    pw.print("  * "); pw.println(rec);
13464                    if (dumpAll) {
13465                        rec.dump(pw, "    ");
13466                    }
13467                } else {
13468                    pw.print("  * "); pw.println(ref);
13469                }
13470            }
13471        }
13472
13473        if (!printed) {
13474            pw.println("  (nothing)");
13475        }
13476    }
13477
13478    private static final int dumpProcessList(PrintWriter pw,
13479            ActivityManagerService service, List list,
13480            String prefix, String normalLabel, String persistentLabel,
13481            String dumpPackage) {
13482        int numPers = 0;
13483        final int N = list.size()-1;
13484        for (int i=N; i>=0; i--) {
13485            ProcessRecord r = (ProcessRecord)list.get(i);
13486            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13487                continue;
13488            }
13489            pw.println(String.format("%s%s #%2d: %s",
13490                    prefix, (r.persistent ? persistentLabel : normalLabel),
13491                    i, r.toString()));
13492            if (r.persistent) {
13493                numPers++;
13494            }
13495        }
13496        return numPers;
13497    }
13498
13499    private static final boolean dumpProcessOomList(PrintWriter pw,
13500            ActivityManagerService service, List<ProcessRecord> origList,
13501            String prefix, String normalLabel, String persistentLabel,
13502            boolean inclDetails, String dumpPackage) {
13503
13504        ArrayList<Pair<ProcessRecord, Integer>> list
13505                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13506        for (int i=0; i<origList.size(); i++) {
13507            ProcessRecord r = origList.get(i);
13508            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13509                continue;
13510            }
13511            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13512        }
13513
13514        if (list.size() <= 0) {
13515            return false;
13516        }
13517
13518        Comparator<Pair<ProcessRecord, Integer>> comparator
13519                = new Comparator<Pair<ProcessRecord, Integer>>() {
13520            @Override
13521            public int compare(Pair<ProcessRecord, Integer> object1,
13522                    Pair<ProcessRecord, Integer> object2) {
13523                if (object1.first.setAdj != object2.first.setAdj) {
13524                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13525                }
13526                if (object1.second.intValue() != object2.second.intValue()) {
13527                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13528                }
13529                return 0;
13530            }
13531        };
13532
13533        Collections.sort(list, comparator);
13534
13535        final long curRealtime = SystemClock.elapsedRealtime();
13536        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13537        final long curUptime = SystemClock.uptimeMillis();
13538        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13539
13540        for (int i=list.size()-1; i>=0; i--) {
13541            ProcessRecord r = list.get(i).first;
13542            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13543            char schedGroup;
13544            switch (r.setSchedGroup) {
13545                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13546                    schedGroup = 'B';
13547                    break;
13548                case Process.THREAD_GROUP_DEFAULT:
13549                    schedGroup = 'F';
13550                    break;
13551                default:
13552                    schedGroup = '?';
13553                    break;
13554            }
13555            char foreground;
13556            if (r.foregroundActivities) {
13557                foreground = 'A';
13558            } else if (r.foregroundServices) {
13559                foreground = 'S';
13560            } else {
13561                foreground = ' ';
13562            }
13563            String procState = ProcessList.makeProcStateString(r.curProcState);
13564            pw.print(prefix);
13565            pw.print(r.persistent ? persistentLabel : normalLabel);
13566            pw.print(" #");
13567            int num = (origList.size()-1)-list.get(i).second;
13568            if (num < 10) pw.print(' ');
13569            pw.print(num);
13570            pw.print(": ");
13571            pw.print(oomAdj);
13572            pw.print(' ');
13573            pw.print(schedGroup);
13574            pw.print('/');
13575            pw.print(foreground);
13576            pw.print('/');
13577            pw.print(procState);
13578            pw.print(" trm:");
13579            if (r.trimMemoryLevel < 10) pw.print(' ');
13580            pw.print(r.trimMemoryLevel);
13581            pw.print(' ');
13582            pw.print(r.toShortString());
13583            pw.print(" (");
13584            pw.print(r.adjType);
13585            pw.println(')');
13586            if (r.adjSource != null || r.adjTarget != null) {
13587                pw.print(prefix);
13588                pw.print("    ");
13589                if (r.adjTarget instanceof ComponentName) {
13590                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13591                } else if (r.adjTarget != null) {
13592                    pw.print(r.adjTarget.toString());
13593                } else {
13594                    pw.print("{null}");
13595                }
13596                pw.print("<=");
13597                if (r.adjSource instanceof ProcessRecord) {
13598                    pw.print("Proc{");
13599                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13600                    pw.println("}");
13601                } else if (r.adjSource != null) {
13602                    pw.println(r.adjSource.toString());
13603                } else {
13604                    pw.println("{null}");
13605                }
13606            }
13607            if (inclDetails) {
13608                pw.print(prefix);
13609                pw.print("    ");
13610                pw.print("oom: max="); pw.print(r.maxAdj);
13611                pw.print(" curRaw="); pw.print(r.curRawAdj);
13612                pw.print(" setRaw="); pw.print(r.setRawAdj);
13613                pw.print(" cur="); pw.print(r.curAdj);
13614                pw.print(" set="); pw.println(r.setAdj);
13615                pw.print(prefix);
13616                pw.print("    ");
13617                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13618                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13619                pw.print(" lastPss="); pw.print(r.lastPss);
13620                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13621                pw.print(prefix);
13622                pw.print("    ");
13623                pw.print("cached="); pw.print(r.cached);
13624                pw.print(" empty="); pw.print(r.empty);
13625                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13626
13627                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13628                    if (r.lastWakeTime != 0) {
13629                        long wtime;
13630                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13631                        synchronized (stats) {
13632                            wtime = stats.getProcessWakeTime(r.info.uid,
13633                                    r.pid, curRealtime);
13634                        }
13635                        long timeUsed = wtime - r.lastWakeTime;
13636                        pw.print(prefix);
13637                        pw.print("    ");
13638                        pw.print("keep awake over ");
13639                        TimeUtils.formatDuration(realtimeSince, pw);
13640                        pw.print(" used ");
13641                        TimeUtils.formatDuration(timeUsed, pw);
13642                        pw.print(" (");
13643                        pw.print((timeUsed*100)/realtimeSince);
13644                        pw.println("%)");
13645                    }
13646                    if (r.lastCpuTime != 0) {
13647                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13648                        pw.print(prefix);
13649                        pw.print("    ");
13650                        pw.print("run cpu over ");
13651                        TimeUtils.formatDuration(uptimeSince, pw);
13652                        pw.print(" used ");
13653                        TimeUtils.formatDuration(timeUsed, pw);
13654                        pw.print(" (");
13655                        pw.print((timeUsed*100)/uptimeSince);
13656                        pw.println("%)");
13657                    }
13658                }
13659            }
13660        }
13661        return true;
13662    }
13663
13664    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13665            String[] args) {
13666        ArrayList<ProcessRecord> procs;
13667        synchronized (this) {
13668            if (args != null && args.length > start
13669                    && args[start].charAt(0) != '-') {
13670                procs = new ArrayList<ProcessRecord>();
13671                int pid = -1;
13672                try {
13673                    pid = Integer.parseInt(args[start]);
13674                } catch (NumberFormatException e) {
13675                }
13676                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13677                    ProcessRecord proc = mLruProcesses.get(i);
13678                    if (proc.pid == pid) {
13679                        procs.add(proc);
13680                    } else if (allPkgs && proc.pkgList != null
13681                            && proc.pkgList.containsKey(args[start])) {
13682                        procs.add(proc);
13683                    } else if (proc.processName.equals(args[start])) {
13684                        procs.add(proc);
13685                    }
13686                }
13687                if (procs.size() <= 0) {
13688                    return null;
13689                }
13690            } else {
13691                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13692            }
13693        }
13694        return procs;
13695    }
13696
13697    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13698            PrintWriter pw, String[] args) {
13699        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13700        if (procs == null) {
13701            pw.println("No process found for: " + args[0]);
13702            return;
13703        }
13704
13705        long uptime = SystemClock.uptimeMillis();
13706        long realtime = SystemClock.elapsedRealtime();
13707        pw.println("Applications Graphics Acceleration Info:");
13708        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13709
13710        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13711            ProcessRecord r = procs.get(i);
13712            if (r.thread != null) {
13713                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13714                pw.flush();
13715                try {
13716                    TransferPipe tp = new TransferPipe();
13717                    try {
13718                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13719                        tp.go(fd);
13720                    } finally {
13721                        tp.kill();
13722                    }
13723                } catch (IOException e) {
13724                    pw.println("Failure while dumping the app: " + r);
13725                    pw.flush();
13726                } catch (RemoteException e) {
13727                    pw.println("Got a RemoteException while dumping the app " + r);
13728                    pw.flush();
13729                }
13730            }
13731        }
13732    }
13733
13734    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13735        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13736        if (procs == null) {
13737            pw.println("No process found for: " + args[0]);
13738            return;
13739        }
13740
13741        pw.println("Applications Database Info:");
13742
13743        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13744            ProcessRecord r = procs.get(i);
13745            if (r.thread != null) {
13746                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13747                pw.flush();
13748                try {
13749                    TransferPipe tp = new TransferPipe();
13750                    try {
13751                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13752                        tp.go(fd);
13753                    } finally {
13754                        tp.kill();
13755                    }
13756                } catch (IOException e) {
13757                    pw.println("Failure while dumping the app: " + r);
13758                    pw.flush();
13759                } catch (RemoteException e) {
13760                    pw.println("Got a RemoteException while dumping the app " + r);
13761                    pw.flush();
13762                }
13763            }
13764        }
13765    }
13766
13767    final static class MemItem {
13768        final boolean isProc;
13769        final String label;
13770        final String shortLabel;
13771        final long pss;
13772        final int id;
13773        final boolean hasActivities;
13774        ArrayList<MemItem> subitems;
13775
13776        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13777                boolean _hasActivities) {
13778            isProc = true;
13779            label = _label;
13780            shortLabel = _shortLabel;
13781            pss = _pss;
13782            id = _id;
13783            hasActivities = _hasActivities;
13784        }
13785
13786        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13787            isProc = false;
13788            label = _label;
13789            shortLabel = _shortLabel;
13790            pss = _pss;
13791            id = _id;
13792            hasActivities = false;
13793        }
13794    }
13795
13796    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13797            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13798        if (sort && !isCompact) {
13799            Collections.sort(items, new Comparator<MemItem>() {
13800                @Override
13801                public int compare(MemItem lhs, MemItem rhs) {
13802                    if (lhs.pss < rhs.pss) {
13803                        return 1;
13804                    } else if (lhs.pss > rhs.pss) {
13805                        return -1;
13806                    }
13807                    return 0;
13808                }
13809            });
13810        }
13811
13812        for (int i=0; i<items.size(); i++) {
13813            MemItem mi = items.get(i);
13814            if (!isCompact) {
13815                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13816            } else if (mi.isProc) {
13817                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13818                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13819                pw.println(mi.hasActivities ? ",a" : ",e");
13820            } else {
13821                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13822                pw.println(mi.pss);
13823            }
13824            if (mi.subitems != null) {
13825                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13826                        true, isCompact);
13827            }
13828        }
13829    }
13830
13831    // These are in KB.
13832    static final long[] DUMP_MEM_BUCKETS = new long[] {
13833        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13834        120*1024, 160*1024, 200*1024,
13835        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13836        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13837    };
13838
13839    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13840            boolean stackLike) {
13841        int start = label.lastIndexOf('.');
13842        if (start >= 0) start++;
13843        else start = 0;
13844        int end = label.length();
13845        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13846            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13847                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13848                out.append(bucket);
13849                out.append(stackLike ? "MB." : "MB ");
13850                out.append(label, start, end);
13851                return;
13852            }
13853        }
13854        out.append(memKB/1024);
13855        out.append(stackLike ? "MB." : "MB ");
13856        out.append(label, start, end);
13857    }
13858
13859    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13860            ProcessList.NATIVE_ADJ,
13861            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13862            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13863            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13864            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13865            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13866            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13867    };
13868    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13869            "Native",
13870            "System", "Persistent", "Persistent Service", "Foreground",
13871            "Visible", "Perceptible",
13872            "Heavy Weight", "Backup",
13873            "A Services", "Home",
13874            "Previous", "B Services", "Cached"
13875    };
13876    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13877            "native",
13878            "sys", "pers", "persvc", "fore",
13879            "vis", "percept",
13880            "heavy", "backup",
13881            "servicea", "home",
13882            "prev", "serviceb", "cached"
13883    };
13884
13885    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13886            long realtime, boolean isCheckinRequest, boolean isCompact) {
13887        if (isCheckinRequest || isCompact) {
13888            // short checkin version
13889            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13890        } else {
13891            pw.println("Applications Memory Usage (kB):");
13892            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13893        }
13894    }
13895
13896    private static final int KSM_SHARED = 0;
13897    private static final int KSM_SHARING = 1;
13898    private static final int KSM_UNSHARED = 2;
13899    private static final int KSM_VOLATILE = 3;
13900
13901    private final long[] getKsmInfo() {
13902        long[] longOut = new long[4];
13903        final int[] SINGLE_LONG_FORMAT = new int[] {
13904            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13905        };
13906        long[] longTmp = new long[1];
13907        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13908                SINGLE_LONG_FORMAT, null, longTmp, null);
13909        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13910        longTmp[0] = 0;
13911        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13912                SINGLE_LONG_FORMAT, null, longTmp, null);
13913        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13914        longTmp[0] = 0;
13915        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13916                SINGLE_LONG_FORMAT, null, longTmp, null);
13917        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13918        longTmp[0] = 0;
13919        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13920                SINGLE_LONG_FORMAT, null, longTmp, null);
13921        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13922        return longOut;
13923    }
13924
13925    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13926            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13927        boolean dumpDetails = false;
13928        boolean dumpFullDetails = false;
13929        boolean dumpDalvik = false;
13930        boolean oomOnly = false;
13931        boolean isCompact = false;
13932        boolean localOnly = false;
13933        boolean packages = false;
13934
13935        int opti = 0;
13936        while (opti < args.length) {
13937            String opt = args[opti];
13938            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13939                break;
13940            }
13941            opti++;
13942            if ("-a".equals(opt)) {
13943                dumpDetails = true;
13944                dumpFullDetails = true;
13945                dumpDalvik = true;
13946            } else if ("-d".equals(opt)) {
13947                dumpDalvik = true;
13948            } else if ("-c".equals(opt)) {
13949                isCompact = true;
13950            } else if ("--oom".equals(opt)) {
13951                oomOnly = true;
13952            } else if ("--local".equals(opt)) {
13953                localOnly = true;
13954            } else if ("--package".equals(opt)) {
13955                packages = true;
13956            } else if ("-h".equals(opt)) {
13957                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13958                pw.println("  -a: include all available information for each process.");
13959                pw.println("  -d: include dalvik details when dumping process details.");
13960                pw.println("  -c: dump in a compact machine-parseable representation.");
13961                pw.println("  --oom: only show processes organized by oom adj.");
13962                pw.println("  --local: only collect details locally, don't call process.");
13963                pw.println("  --package: interpret process arg as package, dumping all");
13964                pw.println("             processes that have loaded that package.");
13965                pw.println("If [process] is specified it can be the name or ");
13966                pw.println("pid of a specific process to dump.");
13967                return;
13968            } else {
13969                pw.println("Unknown argument: " + opt + "; use -h for help");
13970            }
13971        }
13972
13973        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13974        long uptime = SystemClock.uptimeMillis();
13975        long realtime = SystemClock.elapsedRealtime();
13976        final long[] tmpLong = new long[1];
13977
13978        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13979        if (procs == null) {
13980            // No Java processes.  Maybe they want to print a native process.
13981            if (args != null && args.length > opti
13982                    && args[opti].charAt(0) != '-') {
13983                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13984                        = new ArrayList<ProcessCpuTracker.Stats>();
13985                updateCpuStatsNow();
13986                int findPid = -1;
13987                try {
13988                    findPid = Integer.parseInt(args[opti]);
13989                } catch (NumberFormatException e) {
13990                }
13991                synchronized (mProcessCpuTracker) {
13992                    final int N = mProcessCpuTracker.countStats();
13993                    for (int i=0; i<N; i++) {
13994                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13995                        if (st.pid == findPid || (st.baseName != null
13996                                && st.baseName.equals(args[opti]))) {
13997                            nativeProcs.add(st);
13998                        }
13999                    }
14000                }
14001                if (nativeProcs.size() > 0) {
14002                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14003                            isCompact);
14004                    Debug.MemoryInfo mi = null;
14005                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14006                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14007                        final int pid = r.pid;
14008                        if (!isCheckinRequest && dumpDetails) {
14009                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14010                        }
14011                        if (mi == null) {
14012                            mi = new Debug.MemoryInfo();
14013                        }
14014                        if (dumpDetails || (!brief && !oomOnly)) {
14015                            Debug.getMemoryInfo(pid, mi);
14016                        } else {
14017                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14018                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14019                        }
14020                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14021                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14022                        if (isCheckinRequest) {
14023                            pw.println();
14024                        }
14025                    }
14026                    return;
14027                }
14028            }
14029            pw.println("No process found for: " + args[opti]);
14030            return;
14031        }
14032
14033        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14034            dumpDetails = true;
14035        }
14036
14037        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14038
14039        String[] innerArgs = new String[args.length-opti];
14040        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14041
14042        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14043        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14044        long nativePss = 0;
14045        long dalvikPss = 0;
14046        long otherPss = 0;
14047        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14048
14049        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14050        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14051                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14052
14053        long totalPss = 0;
14054        long cachedPss = 0;
14055
14056        Debug.MemoryInfo mi = null;
14057        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14058            final ProcessRecord r = procs.get(i);
14059            final IApplicationThread thread;
14060            final int pid;
14061            final int oomAdj;
14062            final boolean hasActivities;
14063            synchronized (this) {
14064                thread = r.thread;
14065                pid = r.pid;
14066                oomAdj = r.getSetAdjWithServices();
14067                hasActivities = r.activities.size() > 0;
14068            }
14069            if (thread != null) {
14070                if (!isCheckinRequest && dumpDetails) {
14071                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14072                }
14073                if (mi == null) {
14074                    mi = new Debug.MemoryInfo();
14075                }
14076                if (dumpDetails || (!brief && !oomOnly)) {
14077                    Debug.getMemoryInfo(pid, mi);
14078                } else {
14079                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14080                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14081                }
14082                if (dumpDetails) {
14083                    if (localOnly) {
14084                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14085                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14086                        if (isCheckinRequest) {
14087                            pw.println();
14088                        }
14089                    } else {
14090                        try {
14091                            pw.flush();
14092                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14093                                    dumpDalvik, innerArgs);
14094                        } catch (RemoteException e) {
14095                            if (!isCheckinRequest) {
14096                                pw.println("Got RemoteException!");
14097                                pw.flush();
14098                            }
14099                        }
14100                    }
14101                }
14102
14103                final long myTotalPss = mi.getTotalPss();
14104                final long myTotalUss = mi.getTotalUss();
14105
14106                synchronized (this) {
14107                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14108                        // Record this for posterity if the process has been stable.
14109                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14110                    }
14111                }
14112
14113                if (!isCheckinRequest && mi != null) {
14114                    totalPss += myTotalPss;
14115                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14116                            (hasActivities ? " / activities)" : ")"),
14117                            r.processName, myTotalPss, pid, hasActivities);
14118                    procMems.add(pssItem);
14119                    procMemsMap.put(pid, pssItem);
14120
14121                    nativePss += mi.nativePss;
14122                    dalvikPss += mi.dalvikPss;
14123                    otherPss += mi.otherPss;
14124                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14125                        long mem = mi.getOtherPss(j);
14126                        miscPss[j] += mem;
14127                        otherPss -= mem;
14128                    }
14129
14130                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14131                        cachedPss += myTotalPss;
14132                    }
14133
14134                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14135                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14136                                || oomIndex == (oomPss.length-1)) {
14137                            oomPss[oomIndex] += myTotalPss;
14138                            if (oomProcs[oomIndex] == null) {
14139                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14140                            }
14141                            oomProcs[oomIndex].add(pssItem);
14142                            break;
14143                        }
14144                    }
14145                }
14146            }
14147        }
14148
14149        long nativeProcTotalPss = 0;
14150
14151        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14152            // If we are showing aggregations, also look for native processes to
14153            // include so that our aggregations are more accurate.
14154            updateCpuStatsNow();
14155            mi = null;
14156            synchronized (mProcessCpuTracker) {
14157                final int N = mProcessCpuTracker.countStats();
14158                for (int i=0; i<N; i++) {
14159                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14160                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14161                        if (mi == null) {
14162                            mi = new Debug.MemoryInfo();
14163                        }
14164                        if (!brief && !oomOnly) {
14165                            Debug.getMemoryInfo(st.pid, mi);
14166                        } else {
14167                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14168                            mi.nativePrivateDirty = (int)tmpLong[0];
14169                        }
14170
14171                        final long myTotalPss = mi.getTotalPss();
14172                        totalPss += myTotalPss;
14173                        nativeProcTotalPss += myTotalPss;
14174
14175                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14176                                st.name, myTotalPss, st.pid, false);
14177                        procMems.add(pssItem);
14178
14179                        nativePss += mi.nativePss;
14180                        dalvikPss += mi.dalvikPss;
14181                        otherPss += mi.otherPss;
14182                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14183                            long mem = mi.getOtherPss(j);
14184                            miscPss[j] += mem;
14185                            otherPss -= mem;
14186                        }
14187                        oomPss[0] += myTotalPss;
14188                        if (oomProcs[0] == null) {
14189                            oomProcs[0] = new ArrayList<MemItem>();
14190                        }
14191                        oomProcs[0].add(pssItem);
14192                    }
14193                }
14194            }
14195
14196            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14197
14198            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14199            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14200            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14201            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14202                String label = Debug.MemoryInfo.getOtherLabel(j);
14203                catMems.add(new MemItem(label, label, miscPss[j], j));
14204            }
14205
14206            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14207            for (int j=0; j<oomPss.length; j++) {
14208                if (oomPss[j] != 0) {
14209                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14210                            : DUMP_MEM_OOM_LABEL[j];
14211                    MemItem item = new MemItem(label, label, oomPss[j],
14212                            DUMP_MEM_OOM_ADJ[j]);
14213                    item.subitems = oomProcs[j];
14214                    oomMems.add(item);
14215                }
14216            }
14217
14218            if (!brief && !oomOnly && !isCompact) {
14219                pw.println();
14220                pw.println("Total PSS by process:");
14221                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14222                pw.println();
14223            }
14224            if (!isCompact) {
14225                pw.println("Total PSS by OOM adjustment:");
14226            }
14227            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14228            if (!brief && !oomOnly) {
14229                PrintWriter out = categoryPw != null ? categoryPw : pw;
14230                if (!isCompact) {
14231                    out.println();
14232                    out.println("Total PSS by category:");
14233                }
14234                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14235            }
14236            if (!isCompact) {
14237                pw.println();
14238            }
14239            MemInfoReader memInfo = new MemInfoReader();
14240            memInfo.readMemInfo();
14241            if (nativeProcTotalPss > 0) {
14242                synchronized (this) {
14243                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14244                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14245                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14246                }
14247            }
14248            if (!brief) {
14249                if (!isCompact) {
14250                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14251                    pw.print(" kB (status ");
14252                    switch (mLastMemoryLevel) {
14253                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14254                            pw.println("normal)");
14255                            break;
14256                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14257                            pw.println("moderate)");
14258                            break;
14259                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14260                            pw.println("low)");
14261                            break;
14262                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14263                            pw.println("critical)");
14264                            break;
14265                        default:
14266                            pw.print(mLastMemoryLevel);
14267                            pw.println(")");
14268                            break;
14269                    }
14270                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14271                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14272                            pw.print(cachedPss); pw.print(" cached pss + ");
14273                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14274                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14275                } else {
14276                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14277                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14278                            + memInfo.getFreeSizeKb()); pw.print(",");
14279                    pw.println(totalPss - cachedPss);
14280                }
14281            }
14282            if (!isCompact) {
14283                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14284                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14285                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14286                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14287                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14288                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14289                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14290            }
14291            if (!brief) {
14292                if (memInfo.getZramTotalSizeKb() != 0) {
14293                    if (!isCompact) {
14294                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14295                                pw.print(" kB physical used for ");
14296                                pw.print(memInfo.getSwapTotalSizeKb()
14297                                        - memInfo.getSwapFreeSizeKb());
14298                                pw.print(" kB in swap (");
14299                                pw.print(memInfo.getSwapTotalSizeKb());
14300                                pw.println(" kB total swap)");
14301                    } else {
14302                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14303                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14304                                pw.println(memInfo.getSwapFreeSizeKb());
14305                    }
14306                }
14307                final long[] ksm = getKsmInfo();
14308                if (!isCompact) {
14309                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14310                            || ksm[KSM_VOLATILE] != 0) {
14311                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14312                                pw.print(" kB saved from shared ");
14313                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14314                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14315                                pw.print(" kB unshared; ");
14316                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14317                    }
14318                    pw.print("   Tuning: ");
14319                    pw.print(ActivityManager.staticGetMemoryClass());
14320                    pw.print(" (large ");
14321                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14322                    pw.print("), oom ");
14323                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14324                    pw.print(" kB");
14325                    pw.print(", restore limit ");
14326                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14327                    pw.print(" kB");
14328                    if (ActivityManager.isLowRamDeviceStatic()) {
14329                        pw.print(" (low-ram)");
14330                    }
14331                    if (ActivityManager.isHighEndGfx()) {
14332                        pw.print(" (high-end-gfx)");
14333                    }
14334                    pw.println();
14335                } else {
14336                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14337                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14338                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14339                    pw.print("tuning,");
14340                    pw.print(ActivityManager.staticGetMemoryClass());
14341                    pw.print(',');
14342                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14343                    pw.print(',');
14344                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14345                    if (ActivityManager.isLowRamDeviceStatic()) {
14346                        pw.print(",low-ram");
14347                    }
14348                    if (ActivityManager.isHighEndGfx()) {
14349                        pw.print(",high-end-gfx");
14350                    }
14351                    pw.println();
14352                }
14353            }
14354        }
14355    }
14356
14357    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14358            long memtrack, String name) {
14359        sb.append("  ");
14360        sb.append(ProcessList.makeOomAdjString(oomAdj));
14361        sb.append(' ');
14362        sb.append(ProcessList.makeProcStateString(procState));
14363        sb.append(' ');
14364        ProcessList.appendRamKb(sb, pss);
14365        sb.append(" kB: ");
14366        sb.append(name);
14367        if (memtrack > 0) {
14368            sb.append(" (");
14369            sb.append(memtrack);
14370            sb.append(" kB memtrack)");
14371        }
14372    }
14373
14374    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14375        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14376        sb.append(" (pid ");
14377        sb.append(mi.pid);
14378        sb.append(") ");
14379        sb.append(mi.adjType);
14380        sb.append('\n');
14381        if (mi.adjReason != null) {
14382            sb.append("                      ");
14383            sb.append(mi.adjReason);
14384            sb.append('\n');
14385        }
14386    }
14387
14388    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14389        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14390        for (int i=0, N=memInfos.size(); i<N; i++) {
14391            ProcessMemInfo mi = memInfos.get(i);
14392            infoMap.put(mi.pid, mi);
14393        }
14394        updateCpuStatsNow();
14395        long[] memtrackTmp = new long[1];
14396        synchronized (mProcessCpuTracker) {
14397            final int N = mProcessCpuTracker.countStats();
14398            for (int i=0; i<N; i++) {
14399                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14400                if (st.vsize > 0) {
14401                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14402                    if (pss > 0) {
14403                        if (infoMap.indexOfKey(st.pid) < 0) {
14404                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14405                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14406                            mi.pss = pss;
14407                            mi.memtrack = memtrackTmp[0];
14408                            memInfos.add(mi);
14409                        }
14410                    }
14411                }
14412            }
14413        }
14414
14415        long totalPss = 0;
14416        long totalMemtrack = 0;
14417        for (int i=0, N=memInfos.size(); i<N; i++) {
14418            ProcessMemInfo mi = memInfos.get(i);
14419            if (mi.pss == 0) {
14420                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14421                mi.memtrack = memtrackTmp[0];
14422            }
14423            totalPss += mi.pss;
14424            totalMemtrack += mi.memtrack;
14425        }
14426        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14427            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14428                if (lhs.oomAdj != rhs.oomAdj) {
14429                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14430                }
14431                if (lhs.pss != rhs.pss) {
14432                    return lhs.pss < rhs.pss ? 1 : -1;
14433                }
14434                return 0;
14435            }
14436        });
14437
14438        StringBuilder tag = new StringBuilder(128);
14439        StringBuilder stack = new StringBuilder(128);
14440        tag.append("Low on memory -- ");
14441        appendMemBucket(tag, totalPss, "total", false);
14442        appendMemBucket(stack, totalPss, "total", true);
14443
14444        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14445        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14446        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14447
14448        boolean firstLine = true;
14449        int lastOomAdj = Integer.MIN_VALUE;
14450        long extraNativeRam = 0;
14451        long extraNativeMemtrack = 0;
14452        long cachedPss = 0;
14453        for (int i=0, N=memInfos.size(); i<N; i++) {
14454            ProcessMemInfo mi = memInfos.get(i);
14455
14456            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14457                cachedPss += mi.pss;
14458            }
14459
14460            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14461                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14462                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14463                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14464                if (lastOomAdj != mi.oomAdj) {
14465                    lastOomAdj = mi.oomAdj;
14466                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14467                        tag.append(" / ");
14468                    }
14469                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14470                        if (firstLine) {
14471                            stack.append(":");
14472                            firstLine = false;
14473                        }
14474                        stack.append("\n\t at ");
14475                    } else {
14476                        stack.append("$");
14477                    }
14478                } else {
14479                    tag.append(" ");
14480                    stack.append("$");
14481                }
14482                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14483                    appendMemBucket(tag, mi.pss, mi.name, false);
14484                }
14485                appendMemBucket(stack, mi.pss, mi.name, true);
14486                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14487                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14488                    stack.append("(");
14489                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14490                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14491                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14492                            stack.append(":");
14493                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14494                        }
14495                    }
14496                    stack.append(")");
14497                }
14498            }
14499
14500            appendMemInfo(fullNativeBuilder, mi);
14501            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14502                // The short form only has native processes that are >= 512K.
14503                if (mi.pss >= 512) {
14504                    appendMemInfo(shortNativeBuilder, mi);
14505                } else {
14506                    extraNativeRam += mi.pss;
14507                    extraNativeMemtrack += mi.memtrack;
14508                }
14509            } else {
14510                // Short form has all other details, but if we have collected RAM
14511                // from smaller native processes let's dump a summary of that.
14512                if (extraNativeRam > 0) {
14513                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14514                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14515                    shortNativeBuilder.append('\n');
14516                    extraNativeRam = 0;
14517                }
14518                appendMemInfo(fullJavaBuilder, mi);
14519            }
14520        }
14521
14522        fullJavaBuilder.append("           ");
14523        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14524        fullJavaBuilder.append(" kB: TOTAL");
14525        if (totalMemtrack > 0) {
14526            fullJavaBuilder.append(" (");
14527            fullJavaBuilder.append(totalMemtrack);
14528            fullJavaBuilder.append(" kB memtrack)");
14529        } else {
14530        }
14531        fullJavaBuilder.append("\n");
14532
14533        MemInfoReader memInfo = new MemInfoReader();
14534        memInfo.readMemInfo();
14535        final long[] infos = memInfo.getRawInfo();
14536
14537        StringBuilder memInfoBuilder = new StringBuilder(1024);
14538        Debug.getMemInfo(infos);
14539        memInfoBuilder.append("  MemInfo: ");
14540        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14541        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14542        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14543        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14544        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14545        memInfoBuilder.append("           ");
14546        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14547        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14548        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14549        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14550        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14551            memInfoBuilder.append("  ZRAM: ");
14552            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14553            memInfoBuilder.append(" kB RAM, ");
14554            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14555            memInfoBuilder.append(" kB swap total, ");
14556            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14557            memInfoBuilder.append(" kB swap free\n");
14558        }
14559        final long[] ksm = getKsmInfo();
14560        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14561                || ksm[KSM_VOLATILE] != 0) {
14562            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14563            memInfoBuilder.append(" kB saved from shared ");
14564            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14565            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14566            memInfoBuilder.append(" kB unshared; ");
14567            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14568        }
14569        memInfoBuilder.append("  Free RAM: ");
14570        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14571                + memInfo.getFreeSizeKb());
14572        memInfoBuilder.append(" kB\n");
14573        memInfoBuilder.append("  Used RAM: ");
14574        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14575        memInfoBuilder.append(" kB\n");
14576        memInfoBuilder.append("  Lost RAM: ");
14577        memInfoBuilder.append(memInfo.getTotalSizeKb()
14578                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14579                - memInfo.getKernelUsedSizeKb());
14580        memInfoBuilder.append(" kB\n");
14581        Slog.i(TAG, "Low on memory:");
14582        Slog.i(TAG, shortNativeBuilder.toString());
14583        Slog.i(TAG, fullJavaBuilder.toString());
14584        Slog.i(TAG, memInfoBuilder.toString());
14585
14586        StringBuilder dropBuilder = new StringBuilder(1024);
14587        /*
14588        StringWriter oomSw = new StringWriter();
14589        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14590        StringWriter catSw = new StringWriter();
14591        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14592        String[] emptyArgs = new String[] { };
14593        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14594        oomPw.flush();
14595        String oomString = oomSw.toString();
14596        */
14597        dropBuilder.append("Low on memory:");
14598        dropBuilder.append(stack);
14599        dropBuilder.append('\n');
14600        dropBuilder.append(fullNativeBuilder);
14601        dropBuilder.append(fullJavaBuilder);
14602        dropBuilder.append('\n');
14603        dropBuilder.append(memInfoBuilder);
14604        dropBuilder.append('\n');
14605        /*
14606        dropBuilder.append(oomString);
14607        dropBuilder.append('\n');
14608        */
14609        StringWriter catSw = new StringWriter();
14610        synchronized (ActivityManagerService.this) {
14611            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14612            String[] emptyArgs = new String[] { };
14613            catPw.println();
14614            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14615            catPw.println();
14616            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14617                    false, false, null);
14618            catPw.println();
14619            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14620            catPw.flush();
14621        }
14622        dropBuilder.append(catSw.toString());
14623        addErrorToDropBox("lowmem", null, "system_server", null,
14624                null, tag.toString(), dropBuilder.toString(), null, null);
14625        //Slog.i(TAG, "Sent to dropbox:");
14626        //Slog.i(TAG, dropBuilder.toString());
14627        synchronized (ActivityManagerService.this) {
14628            long now = SystemClock.uptimeMillis();
14629            if (mLastMemUsageReportTime < now) {
14630                mLastMemUsageReportTime = now;
14631            }
14632        }
14633    }
14634
14635    /**
14636     * Searches array of arguments for the specified string
14637     * @param args array of argument strings
14638     * @param value value to search for
14639     * @return true if the value is contained in the array
14640     */
14641    private static boolean scanArgs(String[] args, String value) {
14642        if (args != null) {
14643            for (String arg : args) {
14644                if (value.equals(arg)) {
14645                    return true;
14646                }
14647            }
14648        }
14649        return false;
14650    }
14651
14652    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14653            ContentProviderRecord cpr, boolean always) {
14654        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14655
14656        if (!inLaunching || always) {
14657            synchronized (cpr) {
14658                cpr.launchingApp = null;
14659                cpr.notifyAll();
14660            }
14661            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14662            String names[] = cpr.info.authority.split(";");
14663            for (int j = 0; j < names.length; j++) {
14664                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14665            }
14666        }
14667
14668        for (int i=0; i<cpr.connections.size(); i++) {
14669            ContentProviderConnection conn = cpr.connections.get(i);
14670            if (conn.waiting) {
14671                // If this connection is waiting for the provider, then we don't
14672                // need to mess with its process unless we are always removing
14673                // or for some reason the provider is not currently launching.
14674                if (inLaunching && !always) {
14675                    continue;
14676                }
14677            }
14678            ProcessRecord capp = conn.client;
14679            conn.dead = true;
14680            if (conn.stableCount > 0) {
14681                if (!capp.persistent && capp.thread != null
14682                        && capp.pid != 0
14683                        && capp.pid != MY_PID) {
14684                    capp.kill("depends on provider "
14685                            + cpr.name.flattenToShortString()
14686                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14687                }
14688            } else if (capp.thread != null && conn.provider.provider != null) {
14689                try {
14690                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14691                } catch (RemoteException e) {
14692                }
14693                // In the protocol here, we don't expect the client to correctly
14694                // clean up this connection, we'll just remove it.
14695                cpr.connections.remove(i);
14696                conn.client.conProviders.remove(conn);
14697            }
14698        }
14699
14700        if (inLaunching && always) {
14701            mLaunchingProviders.remove(cpr);
14702        }
14703        return inLaunching;
14704    }
14705
14706    /**
14707     * Main code for cleaning up a process when it has gone away.  This is
14708     * called both as a result of the process dying, or directly when stopping
14709     * a process when running in single process mode.
14710     *
14711     * @return Returns true if the given process has been restarted, so the
14712     * app that was passed in must remain on the process lists.
14713     */
14714    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14715            boolean restarting, boolean allowRestart, int index) {
14716        if (index >= 0) {
14717            removeLruProcessLocked(app);
14718            ProcessList.remove(app.pid);
14719        }
14720
14721        mProcessesToGc.remove(app);
14722        mPendingPssProcesses.remove(app);
14723
14724        // Dismiss any open dialogs.
14725        if (app.crashDialog != null && !app.forceCrashReport) {
14726            app.crashDialog.dismiss();
14727            app.crashDialog = null;
14728        }
14729        if (app.anrDialog != null) {
14730            app.anrDialog.dismiss();
14731            app.anrDialog = null;
14732        }
14733        if (app.waitDialog != null) {
14734            app.waitDialog.dismiss();
14735            app.waitDialog = null;
14736        }
14737
14738        app.crashing = false;
14739        app.notResponding = false;
14740
14741        app.resetPackageList(mProcessStats);
14742        app.unlinkDeathRecipient();
14743        app.makeInactive(mProcessStats);
14744        app.waitingToKill = null;
14745        app.forcingToForeground = null;
14746        updateProcessForegroundLocked(app, false, false);
14747        app.foregroundActivities = false;
14748        app.hasShownUi = false;
14749        app.treatLikeActivity = false;
14750        app.hasAboveClient = false;
14751        app.hasClientActivities = false;
14752
14753        mServices.killServicesLocked(app, allowRestart);
14754
14755        boolean restart = false;
14756
14757        // Remove published content providers.
14758        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14759            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14760            final boolean always = app.bad || !allowRestart;
14761            if (removeDyingProviderLocked(app, cpr, always) || always) {
14762                // We left the provider in the launching list, need to
14763                // restart it.
14764                restart = true;
14765            }
14766
14767            cpr.provider = null;
14768            cpr.proc = null;
14769        }
14770        app.pubProviders.clear();
14771
14772        // Take care of any launching providers waiting for this process.
14773        if (checkAppInLaunchingProvidersLocked(app, false)) {
14774            restart = true;
14775        }
14776
14777        // Unregister from connected content providers.
14778        if (!app.conProviders.isEmpty()) {
14779            for (int i=0; i<app.conProviders.size(); i++) {
14780                ContentProviderConnection conn = app.conProviders.get(i);
14781                conn.provider.connections.remove(conn);
14782            }
14783            app.conProviders.clear();
14784        }
14785
14786        // At this point there may be remaining entries in mLaunchingProviders
14787        // where we were the only one waiting, so they are no longer of use.
14788        // Look for these and clean up if found.
14789        // XXX Commented out for now.  Trying to figure out a way to reproduce
14790        // the actual situation to identify what is actually going on.
14791        if (false) {
14792            for (int i=0; i<mLaunchingProviders.size(); i++) {
14793                ContentProviderRecord cpr = (ContentProviderRecord)
14794                        mLaunchingProviders.get(i);
14795                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14796                    synchronized (cpr) {
14797                        cpr.launchingApp = null;
14798                        cpr.notifyAll();
14799                    }
14800                }
14801            }
14802        }
14803
14804        skipCurrentReceiverLocked(app);
14805
14806        // Unregister any receivers.
14807        for (int i=app.receivers.size()-1; i>=0; i--) {
14808            removeReceiverLocked(app.receivers.valueAt(i));
14809        }
14810        app.receivers.clear();
14811
14812        // If the app is undergoing backup, tell the backup manager about it
14813        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14814            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14815                    + mBackupTarget.appInfo + " died during backup");
14816            try {
14817                IBackupManager bm = IBackupManager.Stub.asInterface(
14818                        ServiceManager.getService(Context.BACKUP_SERVICE));
14819                bm.agentDisconnected(app.info.packageName);
14820            } catch (RemoteException e) {
14821                // can't happen; backup manager is local
14822            }
14823        }
14824
14825        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14826            ProcessChangeItem item = mPendingProcessChanges.get(i);
14827            if (item.pid == app.pid) {
14828                mPendingProcessChanges.remove(i);
14829                mAvailProcessChanges.add(item);
14830            }
14831        }
14832        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14833
14834        // If the caller is restarting this app, then leave it in its
14835        // current lists and let the caller take care of it.
14836        if (restarting) {
14837            return false;
14838        }
14839
14840        if (!app.persistent || app.isolated) {
14841            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14842                    "Removing non-persistent process during cleanup: " + app);
14843            mProcessNames.remove(app.processName, app.uid);
14844            mIsolatedProcesses.remove(app.uid);
14845            if (mHeavyWeightProcess == app) {
14846                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14847                        mHeavyWeightProcess.userId, 0));
14848                mHeavyWeightProcess = null;
14849            }
14850        } else if (!app.removed) {
14851            // This app is persistent, so we need to keep its record around.
14852            // If it is not already on the pending app list, add it there
14853            // and start a new process for it.
14854            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14855                mPersistentStartingProcesses.add(app);
14856                restart = true;
14857            }
14858        }
14859        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14860                "Clean-up removing on hold: " + app);
14861        mProcessesOnHold.remove(app);
14862
14863        if (app == mHomeProcess) {
14864            mHomeProcess = null;
14865        }
14866        if (app == mPreviousProcess) {
14867            mPreviousProcess = null;
14868        }
14869
14870        if (restart && !app.isolated) {
14871            // We have components that still need to be running in the
14872            // process, so re-launch it.
14873            if (index < 0) {
14874                ProcessList.remove(app.pid);
14875            }
14876            mProcessNames.put(app.processName, app.uid, app);
14877            startProcessLocked(app, "restart", app.processName);
14878            return true;
14879        } else if (app.pid > 0 && app.pid != MY_PID) {
14880            // Goodbye!
14881            boolean removed;
14882            synchronized (mPidsSelfLocked) {
14883                mPidsSelfLocked.remove(app.pid);
14884                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14885            }
14886            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14887            if (app.isolated) {
14888                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14889            }
14890            app.setPid(0);
14891        }
14892        return false;
14893    }
14894
14895    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14896        // Look through the content providers we are waiting to have launched,
14897        // and if any run in this process then either schedule a restart of
14898        // the process or kill the client waiting for it if this process has
14899        // gone bad.
14900        int NL = mLaunchingProviders.size();
14901        boolean restart = false;
14902        for (int i=0; i<NL; i++) {
14903            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14904            if (cpr.launchingApp == app) {
14905                if (!alwaysBad && !app.bad) {
14906                    restart = true;
14907                } else {
14908                    removeDyingProviderLocked(app, cpr, true);
14909                    // cpr should have been removed from mLaunchingProviders
14910                    NL = mLaunchingProviders.size();
14911                    i--;
14912                }
14913            }
14914        }
14915        return restart;
14916    }
14917
14918    // =========================================================
14919    // SERVICES
14920    // =========================================================
14921
14922    @Override
14923    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14924            int flags) {
14925        enforceNotIsolatedCaller("getServices");
14926        synchronized (this) {
14927            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14928        }
14929    }
14930
14931    @Override
14932    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14933        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14934        synchronized (this) {
14935            return mServices.getRunningServiceControlPanelLocked(name);
14936        }
14937    }
14938
14939    @Override
14940    public ComponentName startService(IApplicationThread caller, Intent service,
14941            String resolvedType, int userId) {
14942        enforceNotIsolatedCaller("startService");
14943        // Refuse possible leaked file descriptors
14944        if (service != null && service.hasFileDescriptors() == true) {
14945            throw new IllegalArgumentException("File descriptors passed in Intent");
14946        }
14947
14948        if (DEBUG_SERVICE)
14949            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14950        synchronized(this) {
14951            final int callingPid = Binder.getCallingPid();
14952            final int callingUid = Binder.getCallingUid();
14953            final long origId = Binder.clearCallingIdentity();
14954            ComponentName res = mServices.startServiceLocked(caller, service,
14955                    resolvedType, callingPid, callingUid, userId);
14956            Binder.restoreCallingIdentity(origId);
14957            return res;
14958        }
14959    }
14960
14961    ComponentName startServiceInPackage(int uid,
14962            Intent service, String resolvedType, int userId) {
14963        synchronized(this) {
14964            if (DEBUG_SERVICE)
14965                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14966            final long origId = Binder.clearCallingIdentity();
14967            ComponentName res = mServices.startServiceLocked(null, service,
14968                    resolvedType, -1, uid, userId);
14969            Binder.restoreCallingIdentity(origId);
14970            return res;
14971        }
14972    }
14973
14974    @Override
14975    public int stopService(IApplicationThread caller, Intent service,
14976            String resolvedType, int userId) {
14977        enforceNotIsolatedCaller("stopService");
14978        // Refuse possible leaked file descriptors
14979        if (service != null && service.hasFileDescriptors() == true) {
14980            throw new IllegalArgumentException("File descriptors passed in Intent");
14981        }
14982
14983        synchronized(this) {
14984            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14985        }
14986    }
14987
14988    @Override
14989    public IBinder peekService(Intent service, String resolvedType) {
14990        enforceNotIsolatedCaller("peekService");
14991        // Refuse possible leaked file descriptors
14992        if (service != null && service.hasFileDescriptors() == true) {
14993            throw new IllegalArgumentException("File descriptors passed in Intent");
14994        }
14995        synchronized(this) {
14996            return mServices.peekServiceLocked(service, resolvedType);
14997        }
14998    }
14999
15000    @Override
15001    public boolean stopServiceToken(ComponentName className, IBinder token,
15002            int startId) {
15003        synchronized(this) {
15004            return mServices.stopServiceTokenLocked(className, token, startId);
15005        }
15006    }
15007
15008    @Override
15009    public void setServiceForeground(ComponentName className, IBinder token,
15010            int id, Notification notification, boolean removeNotification) {
15011        synchronized(this) {
15012            mServices.setServiceForegroundLocked(className, token, id, notification,
15013                    removeNotification);
15014        }
15015    }
15016
15017    @Override
15018    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15019            boolean requireFull, String name, String callerPackage) {
15020        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15021                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15022    }
15023
15024    int unsafeConvertIncomingUser(int userId) {
15025        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15026                ? mCurrentUserId : userId;
15027    }
15028
15029    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15030            int allowMode, String name, String callerPackage) {
15031        final int callingUserId = UserHandle.getUserId(callingUid);
15032        if (callingUserId == userId) {
15033            return userId;
15034        }
15035
15036        // Note that we may be accessing mCurrentUserId outside of a lock...
15037        // shouldn't be a big deal, if this is being called outside
15038        // of a locked context there is intrinsically a race with
15039        // the value the caller will receive and someone else changing it.
15040        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15041        // we will switch to the calling user if access to the current user fails.
15042        int targetUserId = unsafeConvertIncomingUser(userId);
15043
15044        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15045            final boolean allow;
15046            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15047                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15048                // If the caller has this permission, they always pass go.  And collect $200.
15049                allow = true;
15050            } else if (allowMode == ALLOW_FULL_ONLY) {
15051                // We require full access, sucks to be you.
15052                allow = false;
15053            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15054                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15055                // If the caller does not have either permission, they are always doomed.
15056                allow = false;
15057            } else if (allowMode == ALLOW_NON_FULL) {
15058                // We are blanket allowing non-full access, you lucky caller!
15059                allow = true;
15060            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15061                // We may or may not allow this depending on whether the two users are
15062                // in the same profile.
15063                synchronized (mUserProfileGroupIdsSelfLocked) {
15064                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15065                            UserInfo.NO_PROFILE_GROUP_ID);
15066                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15067                            UserInfo.NO_PROFILE_GROUP_ID);
15068                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15069                            && callingProfile == targetProfile;
15070                }
15071            } else {
15072                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15073            }
15074            if (!allow) {
15075                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15076                    // In this case, they would like to just execute as their
15077                    // owner user instead of failing.
15078                    targetUserId = callingUserId;
15079                } else {
15080                    StringBuilder builder = new StringBuilder(128);
15081                    builder.append("Permission Denial: ");
15082                    builder.append(name);
15083                    if (callerPackage != null) {
15084                        builder.append(" from ");
15085                        builder.append(callerPackage);
15086                    }
15087                    builder.append(" asks to run as user ");
15088                    builder.append(userId);
15089                    builder.append(" but is calling from user ");
15090                    builder.append(UserHandle.getUserId(callingUid));
15091                    builder.append("; this requires ");
15092                    builder.append(INTERACT_ACROSS_USERS_FULL);
15093                    if (allowMode != ALLOW_FULL_ONLY) {
15094                        builder.append(" or ");
15095                        builder.append(INTERACT_ACROSS_USERS);
15096                    }
15097                    String msg = builder.toString();
15098                    Slog.w(TAG, msg);
15099                    throw new SecurityException(msg);
15100                }
15101            }
15102        }
15103        if (!allowAll && targetUserId < 0) {
15104            throw new IllegalArgumentException(
15105                    "Call does not support special user #" + targetUserId);
15106        }
15107        // Check shell permission
15108        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15109            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15110                    targetUserId)) {
15111                throw new SecurityException("Shell does not have permission to access user "
15112                        + targetUserId + "\n " + Debug.getCallers(3));
15113            }
15114        }
15115        return targetUserId;
15116    }
15117
15118    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15119            String className, int flags) {
15120        boolean result = false;
15121        // For apps that don't have pre-defined UIDs, check for permission
15122        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15123            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15124                if (ActivityManager.checkUidPermission(
15125                        INTERACT_ACROSS_USERS,
15126                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15127                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15128                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15129                            + " requests FLAG_SINGLE_USER, but app does not hold "
15130                            + INTERACT_ACROSS_USERS;
15131                    Slog.w(TAG, msg);
15132                    throw new SecurityException(msg);
15133                }
15134                // Permission passed
15135                result = true;
15136            }
15137        } else if ("system".equals(componentProcessName)) {
15138            result = true;
15139        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15140            // Phone app and persistent apps are allowed to export singleuser providers.
15141            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15142                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15143        }
15144        if (DEBUG_MU) {
15145            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15146                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15147        }
15148        return result;
15149    }
15150
15151    /**
15152     * Checks to see if the caller is in the same app as the singleton
15153     * component, or the component is in a special app. It allows special apps
15154     * to export singleton components but prevents exporting singleton
15155     * components for regular apps.
15156     */
15157    boolean isValidSingletonCall(int callingUid, int componentUid) {
15158        int componentAppId = UserHandle.getAppId(componentUid);
15159        return UserHandle.isSameApp(callingUid, componentUid)
15160                || componentAppId == Process.SYSTEM_UID
15161                || componentAppId == Process.PHONE_UID
15162                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15163                        == PackageManager.PERMISSION_GRANTED;
15164    }
15165
15166    public int bindService(IApplicationThread caller, IBinder token,
15167            Intent service, String resolvedType,
15168            IServiceConnection connection, int flags, int userId) {
15169        enforceNotIsolatedCaller("bindService");
15170
15171        // Refuse possible leaked file descriptors
15172        if (service != null && service.hasFileDescriptors() == true) {
15173            throw new IllegalArgumentException("File descriptors passed in Intent");
15174        }
15175
15176        synchronized(this) {
15177            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15178                    connection, flags, userId);
15179        }
15180    }
15181
15182    public boolean unbindService(IServiceConnection connection) {
15183        synchronized (this) {
15184            return mServices.unbindServiceLocked(connection);
15185        }
15186    }
15187
15188    public void publishService(IBinder token, Intent intent, IBinder service) {
15189        // Refuse possible leaked file descriptors
15190        if (intent != null && intent.hasFileDescriptors() == true) {
15191            throw new IllegalArgumentException("File descriptors passed in Intent");
15192        }
15193
15194        synchronized(this) {
15195            if (!(token instanceof ServiceRecord)) {
15196                throw new IllegalArgumentException("Invalid service token");
15197            }
15198            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15199        }
15200    }
15201
15202    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15203        // Refuse possible leaked file descriptors
15204        if (intent != null && intent.hasFileDescriptors() == true) {
15205            throw new IllegalArgumentException("File descriptors passed in Intent");
15206        }
15207
15208        synchronized(this) {
15209            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15210        }
15211    }
15212
15213    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15214        synchronized(this) {
15215            if (!(token instanceof ServiceRecord)) {
15216                throw new IllegalArgumentException("Invalid service token");
15217            }
15218            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15219        }
15220    }
15221
15222    // =========================================================
15223    // BACKUP AND RESTORE
15224    // =========================================================
15225
15226    // Cause the target app to be launched if necessary and its backup agent
15227    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15228    // activity manager to announce its creation.
15229    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15230        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15231        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15232
15233        synchronized(this) {
15234            // !!! TODO: currently no check here that we're already bound
15235            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15236            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15237            synchronized (stats) {
15238                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15239            }
15240
15241            // Backup agent is now in use, its package can't be stopped.
15242            try {
15243                AppGlobals.getPackageManager().setPackageStoppedState(
15244                        app.packageName, false, UserHandle.getUserId(app.uid));
15245            } catch (RemoteException e) {
15246            } catch (IllegalArgumentException e) {
15247                Slog.w(TAG, "Failed trying to unstop package "
15248                        + app.packageName + ": " + e);
15249            }
15250
15251            BackupRecord r = new BackupRecord(ss, app, backupMode);
15252            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15253                    ? new ComponentName(app.packageName, app.backupAgentName)
15254                    : new ComponentName("android", "FullBackupAgent");
15255            // startProcessLocked() returns existing proc's record if it's already running
15256            ProcessRecord proc = startProcessLocked(app.processName, app,
15257                    false, 0, "backup", hostingName, false, false, false);
15258            if (proc == null) {
15259                Slog.e(TAG, "Unable to start backup agent process " + r);
15260                return false;
15261            }
15262
15263            r.app = proc;
15264            mBackupTarget = r;
15265            mBackupAppName = app.packageName;
15266
15267            // Try not to kill the process during backup
15268            updateOomAdjLocked(proc);
15269
15270            // If the process is already attached, schedule the creation of the backup agent now.
15271            // If it is not yet live, this will be done when it attaches to the framework.
15272            if (proc.thread != null) {
15273                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15274                try {
15275                    proc.thread.scheduleCreateBackupAgent(app,
15276                            compatibilityInfoForPackageLocked(app), backupMode);
15277                } catch (RemoteException e) {
15278                    // Will time out on the backup manager side
15279                }
15280            } else {
15281                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15282            }
15283            // Invariants: at this point, the target app process exists and the application
15284            // is either already running or in the process of coming up.  mBackupTarget and
15285            // mBackupAppName describe the app, so that when it binds back to the AM we
15286            // know that it's scheduled for a backup-agent operation.
15287        }
15288
15289        return true;
15290    }
15291
15292    @Override
15293    public void clearPendingBackup() {
15294        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15295        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15296
15297        synchronized (this) {
15298            mBackupTarget = null;
15299            mBackupAppName = null;
15300        }
15301    }
15302
15303    // A backup agent has just come up
15304    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15305        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15306                + " = " + agent);
15307
15308        synchronized(this) {
15309            if (!agentPackageName.equals(mBackupAppName)) {
15310                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15311                return;
15312            }
15313        }
15314
15315        long oldIdent = Binder.clearCallingIdentity();
15316        try {
15317            IBackupManager bm = IBackupManager.Stub.asInterface(
15318                    ServiceManager.getService(Context.BACKUP_SERVICE));
15319            bm.agentConnected(agentPackageName, agent);
15320        } catch (RemoteException e) {
15321            // can't happen; the backup manager service is local
15322        } catch (Exception e) {
15323            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15324            e.printStackTrace();
15325        } finally {
15326            Binder.restoreCallingIdentity(oldIdent);
15327        }
15328    }
15329
15330    // done with this agent
15331    public void unbindBackupAgent(ApplicationInfo appInfo) {
15332        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15333        if (appInfo == null) {
15334            Slog.w(TAG, "unbind backup agent for null app");
15335            return;
15336        }
15337
15338        synchronized(this) {
15339            try {
15340                if (mBackupAppName == null) {
15341                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15342                    return;
15343                }
15344
15345                if (!mBackupAppName.equals(appInfo.packageName)) {
15346                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15347                    return;
15348                }
15349
15350                // Not backing this app up any more; reset its OOM adjustment
15351                final ProcessRecord proc = mBackupTarget.app;
15352                updateOomAdjLocked(proc);
15353
15354                // If the app crashed during backup, 'thread' will be null here
15355                if (proc.thread != null) {
15356                    try {
15357                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15358                                compatibilityInfoForPackageLocked(appInfo));
15359                    } catch (Exception e) {
15360                        Slog.e(TAG, "Exception when unbinding backup agent:");
15361                        e.printStackTrace();
15362                    }
15363                }
15364            } finally {
15365                mBackupTarget = null;
15366                mBackupAppName = null;
15367            }
15368        }
15369    }
15370    // =========================================================
15371    // BROADCASTS
15372    // =========================================================
15373
15374    private final List getStickiesLocked(String action, IntentFilter filter,
15375            List cur, int userId) {
15376        final ContentResolver resolver = mContext.getContentResolver();
15377        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15378        if (stickies == null) {
15379            return cur;
15380        }
15381        final ArrayList<Intent> list = stickies.get(action);
15382        if (list == null) {
15383            return cur;
15384        }
15385        int N = list.size();
15386        for (int i=0; i<N; i++) {
15387            Intent intent = list.get(i);
15388            if (filter.match(resolver, intent, true, TAG) >= 0) {
15389                if (cur == null) {
15390                    cur = new ArrayList<Intent>();
15391                }
15392                cur.add(intent);
15393            }
15394        }
15395        return cur;
15396    }
15397
15398    boolean isPendingBroadcastProcessLocked(int pid) {
15399        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15400                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15401    }
15402
15403    void skipPendingBroadcastLocked(int pid) {
15404            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15405            for (BroadcastQueue queue : mBroadcastQueues) {
15406                queue.skipPendingBroadcastLocked(pid);
15407            }
15408    }
15409
15410    // The app just attached; send any pending broadcasts that it should receive
15411    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15412        boolean didSomething = false;
15413        for (BroadcastQueue queue : mBroadcastQueues) {
15414            didSomething |= queue.sendPendingBroadcastsLocked(app);
15415        }
15416        return didSomething;
15417    }
15418
15419    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15420            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15421        enforceNotIsolatedCaller("registerReceiver");
15422        int callingUid;
15423        int callingPid;
15424        synchronized(this) {
15425            ProcessRecord callerApp = null;
15426            if (caller != null) {
15427                callerApp = getRecordForAppLocked(caller);
15428                if (callerApp == null) {
15429                    throw new SecurityException(
15430                            "Unable to find app for caller " + caller
15431                            + " (pid=" + Binder.getCallingPid()
15432                            + ") when registering receiver " + receiver);
15433                }
15434                if (callerApp.info.uid != Process.SYSTEM_UID &&
15435                        !callerApp.pkgList.containsKey(callerPackage) &&
15436                        !"android".equals(callerPackage)) {
15437                    throw new SecurityException("Given caller package " + callerPackage
15438                            + " is not running in process " + callerApp);
15439                }
15440                callingUid = callerApp.info.uid;
15441                callingPid = callerApp.pid;
15442            } else {
15443                callerPackage = null;
15444                callingUid = Binder.getCallingUid();
15445                callingPid = Binder.getCallingPid();
15446            }
15447
15448            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15449                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15450
15451            List allSticky = null;
15452
15453            // Look for any matching sticky broadcasts...
15454            Iterator actions = filter.actionsIterator();
15455            if (actions != null) {
15456                while (actions.hasNext()) {
15457                    String action = (String)actions.next();
15458                    allSticky = getStickiesLocked(action, filter, allSticky,
15459                            UserHandle.USER_ALL);
15460                    allSticky = getStickiesLocked(action, filter, allSticky,
15461                            UserHandle.getUserId(callingUid));
15462                }
15463            } else {
15464                allSticky = getStickiesLocked(null, filter, allSticky,
15465                        UserHandle.USER_ALL);
15466                allSticky = getStickiesLocked(null, filter, allSticky,
15467                        UserHandle.getUserId(callingUid));
15468            }
15469
15470            // The first sticky in the list is returned directly back to
15471            // the client.
15472            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15473
15474            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15475                    + ": " + sticky);
15476
15477            if (receiver == null) {
15478                return sticky;
15479            }
15480
15481            ReceiverList rl
15482                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15483            if (rl == null) {
15484                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15485                        userId, receiver);
15486                if (rl.app != null) {
15487                    rl.app.receivers.add(rl);
15488                } else {
15489                    try {
15490                        receiver.asBinder().linkToDeath(rl, 0);
15491                    } catch (RemoteException e) {
15492                        return sticky;
15493                    }
15494                    rl.linkedToDeath = true;
15495                }
15496                mRegisteredReceivers.put(receiver.asBinder(), rl);
15497            } else if (rl.uid != callingUid) {
15498                throw new IllegalArgumentException(
15499                        "Receiver requested to register for uid " + callingUid
15500                        + " was previously registered for uid " + rl.uid);
15501            } else if (rl.pid != callingPid) {
15502                throw new IllegalArgumentException(
15503                        "Receiver requested to register for pid " + callingPid
15504                        + " was previously registered for pid " + rl.pid);
15505            } else if (rl.userId != userId) {
15506                throw new IllegalArgumentException(
15507                        "Receiver requested to register for user " + userId
15508                        + " was previously registered for user " + rl.userId);
15509            }
15510            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15511                    permission, callingUid, userId);
15512            rl.add(bf);
15513            if (!bf.debugCheck()) {
15514                Slog.w(TAG, "==> For Dynamic broadast");
15515            }
15516            mReceiverResolver.addFilter(bf);
15517
15518            // Enqueue broadcasts for all existing stickies that match
15519            // this filter.
15520            if (allSticky != null) {
15521                ArrayList receivers = new ArrayList();
15522                receivers.add(bf);
15523
15524                int N = allSticky.size();
15525                for (int i=0; i<N; i++) {
15526                    Intent intent = (Intent)allSticky.get(i);
15527                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15528                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15529                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15530                            null, null, false, true, true, -1);
15531                    queue.enqueueParallelBroadcastLocked(r);
15532                    queue.scheduleBroadcastsLocked();
15533                }
15534            }
15535
15536            return sticky;
15537        }
15538    }
15539
15540    public void unregisterReceiver(IIntentReceiver receiver) {
15541        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15542
15543        final long origId = Binder.clearCallingIdentity();
15544        try {
15545            boolean doTrim = false;
15546
15547            synchronized(this) {
15548                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15549                if (rl != null) {
15550                    if (rl.curBroadcast != null) {
15551                        BroadcastRecord r = rl.curBroadcast;
15552                        final boolean doNext = finishReceiverLocked(
15553                                receiver.asBinder(), r.resultCode, r.resultData,
15554                                r.resultExtras, r.resultAbort);
15555                        if (doNext) {
15556                            doTrim = true;
15557                            r.queue.processNextBroadcast(false);
15558                        }
15559                    }
15560
15561                    if (rl.app != null) {
15562                        rl.app.receivers.remove(rl);
15563                    }
15564                    removeReceiverLocked(rl);
15565                    if (rl.linkedToDeath) {
15566                        rl.linkedToDeath = false;
15567                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15568                    }
15569                }
15570            }
15571
15572            // If we actually concluded any broadcasts, we might now be able
15573            // to trim the recipients' apps from our working set
15574            if (doTrim) {
15575                trimApplications();
15576                return;
15577            }
15578
15579        } finally {
15580            Binder.restoreCallingIdentity(origId);
15581        }
15582    }
15583
15584    void removeReceiverLocked(ReceiverList rl) {
15585        mRegisteredReceivers.remove(rl.receiver.asBinder());
15586        int N = rl.size();
15587        for (int i=0; i<N; i++) {
15588            mReceiverResolver.removeFilter(rl.get(i));
15589        }
15590    }
15591
15592    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15593        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15594            ProcessRecord r = mLruProcesses.get(i);
15595            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15596                try {
15597                    r.thread.dispatchPackageBroadcast(cmd, packages);
15598                } catch (RemoteException ex) {
15599                }
15600            }
15601        }
15602    }
15603
15604    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15605            int callingUid, int[] users) {
15606        List<ResolveInfo> receivers = null;
15607        try {
15608            HashSet<ComponentName> singleUserReceivers = null;
15609            boolean scannedFirstReceivers = false;
15610            for (int user : users) {
15611                // Skip users that have Shell restrictions
15612                if (callingUid == Process.SHELL_UID
15613                        && getUserManagerLocked().hasUserRestriction(
15614                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15615                    continue;
15616                }
15617                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15618                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15619                if (user != 0 && newReceivers != null) {
15620                    // If this is not the primary user, we need to check for
15621                    // any receivers that should be filtered out.
15622                    for (int i=0; i<newReceivers.size(); i++) {
15623                        ResolveInfo ri = newReceivers.get(i);
15624                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15625                            newReceivers.remove(i);
15626                            i--;
15627                        }
15628                    }
15629                }
15630                if (newReceivers != null && newReceivers.size() == 0) {
15631                    newReceivers = null;
15632                }
15633                if (receivers == null) {
15634                    receivers = newReceivers;
15635                } else if (newReceivers != null) {
15636                    // We need to concatenate the additional receivers
15637                    // found with what we have do far.  This would be easy,
15638                    // but we also need to de-dup any receivers that are
15639                    // singleUser.
15640                    if (!scannedFirstReceivers) {
15641                        // Collect any single user receivers we had already retrieved.
15642                        scannedFirstReceivers = true;
15643                        for (int i=0; i<receivers.size(); i++) {
15644                            ResolveInfo ri = receivers.get(i);
15645                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15646                                ComponentName cn = new ComponentName(
15647                                        ri.activityInfo.packageName, ri.activityInfo.name);
15648                                if (singleUserReceivers == null) {
15649                                    singleUserReceivers = new HashSet<ComponentName>();
15650                                }
15651                                singleUserReceivers.add(cn);
15652                            }
15653                        }
15654                    }
15655                    // Add the new results to the existing results, tracking
15656                    // and de-dupping single user receivers.
15657                    for (int i=0; i<newReceivers.size(); i++) {
15658                        ResolveInfo ri = newReceivers.get(i);
15659                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15660                            ComponentName cn = new ComponentName(
15661                                    ri.activityInfo.packageName, ri.activityInfo.name);
15662                            if (singleUserReceivers == null) {
15663                                singleUserReceivers = new HashSet<ComponentName>();
15664                            }
15665                            if (!singleUserReceivers.contains(cn)) {
15666                                singleUserReceivers.add(cn);
15667                                receivers.add(ri);
15668                            }
15669                        } else {
15670                            receivers.add(ri);
15671                        }
15672                    }
15673                }
15674            }
15675        } catch (RemoteException ex) {
15676            // pm is in same process, this will never happen.
15677        }
15678        return receivers;
15679    }
15680
15681    private final int broadcastIntentLocked(ProcessRecord callerApp,
15682            String callerPackage, Intent intent, String resolvedType,
15683            IIntentReceiver resultTo, int resultCode, String resultData,
15684            Bundle map, String requiredPermission, int appOp,
15685            boolean ordered, boolean sticky, int callingPid, int callingUid,
15686            int userId) {
15687        intent = new Intent(intent);
15688
15689        // By default broadcasts do not go to stopped apps.
15690        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15691
15692        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15693            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15694            + " ordered=" + ordered + " userid=" + userId);
15695        if ((resultTo != null) && !ordered) {
15696            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15697        }
15698
15699        userId = handleIncomingUser(callingPid, callingUid, userId,
15700                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15701
15702        // Make sure that the user who is receiving this broadcast is running.
15703        // If not, we will just skip it.
15704
15705        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15706            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15707                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15708                Slog.w(TAG, "Skipping broadcast of " + intent
15709                        + ": user " + userId + " is stopped");
15710                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15711            }
15712        }
15713
15714        /*
15715         * Prevent non-system code (defined here to be non-persistent
15716         * processes) from sending protected broadcasts.
15717         */
15718        int callingAppId = UserHandle.getAppId(callingUid);
15719        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15720            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15721            || callingAppId == Process.NFC_UID || callingUid == 0) {
15722            // Always okay.
15723        } else if (callerApp == null || !callerApp.persistent) {
15724            try {
15725                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15726                        intent.getAction())) {
15727                    String msg = "Permission Denial: not allowed to send broadcast "
15728                            + intent.getAction() + " from pid="
15729                            + callingPid + ", uid=" + callingUid;
15730                    Slog.w(TAG, msg);
15731                    throw new SecurityException(msg);
15732                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15733                    // Special case for compatibility: we don't want apps to send this,
15734                    // but historically it has not been protected and apps may be using it
15735                    // to poke their own app widget.  So, instead of making it protected,
15736                    // just limit it to the caller.
15737                    if (callerApp == null) {
15738                        String msg = "Permission Denial: not allowed to send broadcast "
15739                                + intent.getAction() + " from unknown caller.";
15740                        Slog.w(TAG, msg);
15741                        throw new SecurityException(msg);
15742                    } else if (intent.getComponent() != null) {
15743                        // They are good enough to send to an explicit component...  verify
15744                        // it is being sent to the calling app.
15745                        if (!intent.getComponent().getPackageName().equals(
15746                                callerApp.info.packageName)) {
15747                            String msg = "Permission Denial: not allowed to send broadcast "
15748                                    + intent.getAction() + " to "
15749                                    + intent.getComponent().getPackageName() + " from "
15750                                    + callerApp.info.packageName;
15751                            Slog.w(TAG, msg);
15752                            throw new SecurityException(msg);
15753                        }
15754                    } else {
15755                        // Limit broadcast to their own package.
15756                        intent.setPackage(callerApp.info.packageName);
15757                    }
15758                }
15759            } catch (RemoteException e) {
15760                Slog.w(TAG, "Remote exception", e);
15761                return ActivityManager.BROADCAST_SUCCESS;
15762            }
15763        }
15764
15765        final String action = intent.getAction();
15766        if (action != null) {
15767            switch (action) {
15768                case Intent.ACTION_UID_REMOVED:
15769                case Intent.ACTION_PACKAGE_REMOVED:
15770                case Intent.ACTION_PACKAGE_CHANGED:
15771                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15772                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15773                    // Handle special intents: if this broadcast is from the package
15774                    // manager about a package being removed, we need to remove all of
15775                    // its activities from the history stack.
15776                    if (checkComponentPermission(
15777                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15778                            callingPid, callingUid, -1, true)
15779                            != PackageManager.PERMISSION_GRANTED) {
15780                        String msg = "Permission Denial: " + intent.getAction()
15781                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15782                                + ", uid=" + callingUid + ")"
15783                                + " requires "
15784                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15785                        Slog.w(TAG, msg);
15786                        throw new SecurityException(msg);
15787                    }
15788                    switch (action) {
15789                        case Intent.ACTION_UID_REMOVED:
15790                            final Bundle intentExtras = intent.getExtras();
15791                            final int uid = intentExtras != null
15792                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15793                            if (uid >= 0) {
15794                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15795                                synchronized (bs) {
15796                                    bs.removeUidStatsLocked(uid);
15797                                }
15798                                mAppOpsService.uidRemoved(uid);
15799                            }
15800                            break;
15801                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15802                            // If resources are unavailable just force stop all those packages
15803                            // and flush the attribute cache as well.
15804                            String list[] =
15805                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15806                            if (list != null && list.length > 0) {
15807                                for (int i = 0; i < list.length; i++) {
15808                                    forceStopPackageLocked(list[i], -1, false, true, true,
15809                                            false, false, userId, "storage unmount");
15810                                }
15811                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15812                                sendPackageBroadcastLocked(
15813                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15814                                        userId);
15815                            }
15816                            break;
15817                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15818                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15819                            break;
15820                        case Intent.ACTION_PACKAGE_REMOVED:
15821                        case Intent.ACTION_PACKAGE_CHANGED:
15822                            Uri data = intent.getData();
15823                            String ssp;
15824                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15825                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15826                                boolean fullUninstall = removed &&
15827                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15828                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15829                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15830                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15831                                            false, true, true, false, fullUninstall, userId,
15832                                            removed ? "pkg removed" : "pkg changed");
15833                                }
15834                                if (removed) {
15835                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15836                                            new String[] {ssp}, userId);
15837                                    if (fullUninstall) {
15838                                        mAppOpsService.packageRemoved(
15839                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15840
15841                                        // Remove all permissions granted from/to this package
15842                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15843
15844                                        removeTasksByPackageNameLocked(ssp, userId);
15845                                    }
15846                                } else {
15847                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15848                                    if (userId == UserHandle.USER_OWNER) {
15849                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15850                                    }
15851                                }
15852                            }
15853                            break;
15854                    }
15855                    break;
15856                case Intent.ACTION_PACKAGE_ADDED:
15857                    // Special case for adding a package: by default turn on compatibility mode.
15858                    Uri data = intent.getData();
15859                    String ssp;
15860                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15861                        final boolean replacing =
15862                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15863                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15864
15865                        if (replacing) {
15866                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15867                        }
15868                        if (userId == UserHandle.USER_OWNER) {
15869                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15870                        }
15871                    }
15872                    break;
15873                case Intent.ACTION_TIMEZONE_CHANGED:
15874                    // If this is the time zone changed action, queue up a message that will reset
15875                    // the timezone of all currently running processes. This message will get
15876                    // queued up before the broadcast happens.
15877                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15878                    break;
15879                case Intent.ACTION_TIME_CHANGED:
15880                    // If the user set the time, let all running processes know.
15881                    final int is24Hour =
15882                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15883                                    : 0;
15884                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15885                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15886                    synchronized (stats) {
15887                        stats.noteCurrentTimeChangedLocked();
15888                    }
15889                    break;
15890                case Intent.ACTION_CLEAR_DNS_CACHE:
15891                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15892                    break;
15893                case Proxy.PROXY_CHANGE_ACTION:
15894                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15895                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15896                    break;
15897            }
15898        }
15899
15900        // Add to the sticky list if requested.
15901        if (sticky) {
15902            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15903                    callingPid, callingUid)
15904                    != PackageManager.PERMISSION_GRANTED) {
15905                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15906                        + callingPid + ", uid=" + callingUid
15907                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15908                Slog.w(TAG, msg);
15909                throw new SecurityException(msg);
15910            }
15911            if (requiredPermission != null) {
15912                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15913                        + " and enforce permission " + requiredPermission);
15914                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15915            }
15916            if (intent.getComponent() != null) {
15917                throw new SecurityException(
15918                        "Sticky broadcasts can't target a specific component");
15919            }
15920            // We use userId directly here, since the "all" target is maintained
15921            // as a separate set of sticky broadcasts.
15922            if (userId != UserHandle.USER_ALL) {
15923                // But first, if this is not a broadcast to all users, then
15924                // make sure it doesn't conflict with an existing broadcast to
15925                // all users.
15926                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15927                        UserHandle.USER_ALL);
15928                if (stickies != null) {
15929                    ArrayList<Intent> list = stickies.get(intent.getAction());
15930                    if (list != null) {
15931                        int N = list.size();
15932                        int i;
15933                        for (i=0; i<N; i++) {
15934                            if (intent.filterEquals(list.get(i))) {
15935                                throw new IllegalArgumentException(
15936                                        "Sticky broadcast " + intent + " for user "
15937                                        + userId + " conflicts with existing global broadcast");
15938                            }
15939                        }
15940                    }
15941                }
15942            }
15943            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15944            if (stickies == null) {
15945                stickies = new ArrayMap<String, ArrayList<Intent>>();
15946                mStickyBroadcasts.put(userId, stickies);
15947            }
15948            ArrayList<Intent> list = stickies.get(intent.getAction());
15949            if (list == null) {
15950                list = new ArrayList<Intent>();
15951                stickies.put(intent.getAction(), list);
15952            }
15953            int N = list.size();
15954            int i;
15955            for (i=0; i<N; i++) {
15956                if (intent.filterEquals(list.get(i))) {
15957                    // This sticky already exists, replace it.
15958                    list.set(i, new Intent(intent));
15959                    break;
15960                }
15961            }
15962            if (i >= N) {
15963                list.add(new Intent(intent));
15964            }
15965        }
15966
15967        int[] users;
15968        if (userId == UserHandle.USER_ALL) {
15969            // Caller wants broadcast to go to all started users.
15970            users = mStartedUserArray;
15971        } else {
15972            // Caller wants broadcast to go to one specific user.
15973            users = new int[] {userId};
15974        }
15975
15976        // Figure out who all will receive this broadcast.
15977        List receivers = null;
15978        List<BroadcastFilter> registeredReceivers = null;
15979        // Need to resolve the intent to interested receivers...
15980        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15981                 == 0) {
15982            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15983        }
15984        if (intent.getComponent() == null) {
15985            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15986                // Query one target user at a time, excluding shell-restricted users
15987                UserManagerService ums = getUserManagerLocked();
15988                for (int i = 0; i < users.length; i++) {
15989                    if (ums.hasUserRestriction(
15990                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15991                        continue;
15992                    }
15993                    List<BroadcastFilter> registeredReceiversForUser =
15994                            mReceiverResolver.queryIntent(intent,
15995                                    resolvedType, false, users[i]);
15996                    if (registeredReceivers == null) {
15997                        registeredReceivers = registeredReceiversForUser;
15998                    } else if (registeredReceiversForUser != null) {
15999                        registeredReceivers.addAll(registeredReceiversForUser);
16000                    }
16001                }
16002            } else {
16003                registeredReceivers = mReceiverResolver.queryIntent(intent,
16004                        resolvedType, false, userId);
16005            }
16006        }
16007
16008        final boolean replacePending =
16009                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16010
16011        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16012                + " replacePending=" + replacePending);
16013
16014        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16015        if (!ordered && NR > 0) {
16016            // If we are not serializing this broadcast, then send the
16017            // registered receivers separately so they don't wait for the
16018            // components to be launched.
16019            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16020            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16021                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16022                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16023                    ordered, sticky, false, userId);
16024            if (DEBUG_BROADCAST) Slog.v(
16025                    TAG, "Enqueueing parallel broadcast " + r);
16026            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16027            if (!replaced) {
16028                queue.enqueueParallelBroadcastLocked(r);
16029                queue.scheduleBroadcastsLocked();
16030            }
16031            registeredReceivers = null;
16032            NR = 0;
16033        }
16034
16035        // Merge into one list.
16036        int ir = 0;
16037        if (receivers != null) {
16038            // A special case for PACKAGE_ADDED: do not allow the package
16039            // being added to see this broadcast.  This prevents them from
16040            // using this as a back door to get run as soon as they are
16041            // installed.  Maybe in the future we want to have a special install
16042            // broadcast or such for apps, but we'd like to deliberately make
16043            // this decision.
16044            String skipPackages[] = null;
16045            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16046                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16047                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16048                Uri data = intent.getData();
16049                if (data != null) {
16050                    String pkgName = data.getSchemeSpecificPart();
16051                    if (pkgName != null) {
16052                        skipPackages = new String[] { pkgName };
16053                    }
16054                }
16055            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16056                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16057            }
16058            if (skipPackages != null && (skipPackages.length > 0)) {
16059                for (String skipPackage : skipPackages) {
16060                    if (skipPackage != null) {
16061                        int NT = receivers.size();
16062                        for (int it=0; it<NT; it++) {
16063                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16064                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16065                                receivers.remove(it);
16066                                it--;
16067                                NT--;
16068                            }
16069                        }
16070                    }
16071                }
16072            }
16073
16074            int NT = receivers != null ? receivers.size() : 0;
16075            int it = 0;
16076            ResolveInfo curt = null;
16077            BroadcastFilter curr = null;
16078            while (it < NT && ir < NR) {
16079                if (curt == null) {
16080                    curt = (ResolveInfo)receivers.get(it);
16081                }
16082                if (curr == null) {
16083                    curr = registeredReceivers.get(ir);
16084                }
16085                if (curr.getPriority() >= curt.priority) {
16086                    // Insert this broadcast record into the final list.
16087                    receivers.add(it, curr);
16088                    ir++;
16089                    curr = null;
16090                    it++;
16091                    NT++;
16092                } else {
16093                    // Skip to the next ResolveInfo in the final list.
16094                    it++;
16095                    curt = null;
16096                }
16097            }
16098        }
16099        while (ir < NR) {
16100            if (receivers == null) {
16101                receivers = new ArrayList();
16102            }
16103            receivers.add(registeredReceivers.get(ir));
16104            ir++;
16105        }
16106
16107        if ((receivers != null && receivers.size() > 0)
16108                || resultTo != null) {
16109            BroadcastQueue queue = broadcastQueueForIntent(intent);
16110            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16111                    callerPackage, callingPid, callingUid, resolvedType,
16112                    requiredPermission, appOp, receivers, resultTo, resultCode,
16113                    resultData, map, ordered, sticky, false, userId);
16114            if (DEBUG_BROADCAST) Slog.v(
16115                    TAG, "Enqueueing ordered broadcast " + r
16116                    + ": prev had " + queue.mOrderedBroadcasts.size());
16117            if (DEBUG_BROADCAST) {
16118                int seq = r.intent.getIntExtra("seq", -1);
16119                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16120            }
16121            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16122            if (!replaced) {
16123                queue.enqueueOrderedBroadcastLocked(r);
16124                queue.scheduleBroadcastsLocked();
16125            }
16126        }
16127
16128        return ActivityManager.BROADCAST_SUCCESS;
16129    }
16130
16131    final Intent verifyBroadcastLocked(Intent intent) {
16132        // Refuse possible leaked file descriptors
16133        if (intent != null && intent.hasFileDescriptors() == true) {
16134            throw new IllegalArgumentException("File descriptors passed in Intent");
16135        }
16136
16137        int flags = intent.getFlags();
16138
16139        if (!mProcessesReady) {
16140            // if the caller really truly claims to know what they're doing, go
16141            // ahead and allow the broadcast without launching any receivers
16142            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16143                intent = new Intent(intent);
16144                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16145            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16146                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16147                        + " before boot completion");
16148                throw new IllegalStateException("Cannot broadcast before boot completed");
16149            }
16150        }
16151
16152        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16153            throw new IllegalArgumentException(
16154                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16155        }
16156
16157        return intent;
16158    }
16159
16160    public final int broadcastIntent(IApplicationThread caller,
16161            Intent intent, String resolvedType, IIntentReceiver resultTo,
16162            int resultCode, String resultData, Bundle map,
16163            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16164        enforceNotIsolatedCaller("broadcastIntent");
16165        synchronized(this) {
16166            intent = verifyBroadcastLocked(intent);
16167
16168            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16169            final int callingPid = Binder.getCallingPid();
16170            final int callingUid = Binder.getCallingUid();
16171            final long origId = Binder.clearCallingIdentity();
16172            int res = broadcastIntentLocked(callerApp,
16173                    callerApp != null ? callerApp.info.packageName : null,
16174                    intent, resolvedType, resultTo,
16175                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16176                    callingPid, callingUid, userId);
16177            Binder.restoreCallingIdentity(origId);
16178            return res;
16179        }
16180    }
16181
16182    int broadcastIntentInPackage(String packageName, int uid,
16183            Intent intent, String resolvedType, IIntentReceiver resultTo,
16184            int resultCode, String resultData, Bundle map,
16185            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16186        synchronized(this) {
16187            intent = verifyBroadcastLocked(intent);
16188
16189            final long origId = Binder.clearCallingIdentity();
16190            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16191                    resultTo, resultCode, resultData, map, requiredPermission,
16192                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16193            Binder.restoreCallingIdentity(origId);
16194            return res;
16195        }
16196    }
16197
16198    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16199        // Refuse possible leaked file descriptors
16200        if (intent != null && intent.hasFileDescriptors() == true) {
16201            throw new IllegalArgumentException("File descriptors passed in Intent");
16202        }
16203
16204        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16205                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16206
16207        synchronized(this) {
16208            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16209                    != PackageManager.PERMISSION_GRANTED) {
16210                String msg = "Permission Denial: unbroadcastIntent() from pid="
16211                        + Binder.getCallingPid()
16212                        + ", uid=" + Binder.getCallingUid()
16213                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16214                Slog.w(TAG, msg);
16215                throw new SecurityException(msg);
16216            }
16217            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16218            if (stickies != null) {
16219                ArrayList<Intent> list = stickies.get(intent.getAction());
16220                if (list != null) {
16221                    int N = list.size();
16222                    int i;
16223                    for (i=0; i<N; i++) {
16224                        if (intent.filterEquals(list.get(i))) {
16225                            list.remove(i);
16226                            break;
16227                        }
16228                    }
16229                    if (list.size() <= 0) {
16230                        stickies.remove(intent.getAction());
16231                    }
16232                }
16233                if (stickies.size() <= 0) {
16234                    mStickyBroadcasts.remove(userId);
16235                }
16236            }
16237        }
16238    }
16239
16240    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16241            String resultData, Bundle resultExtras, boolean resultAbort) {
16242        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16243        if (r == null) {
16244            Slog.w(TAG, "finishReceiver called but not found on queue");
16245            return false;
16246        }
16247
16248        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16249    }
16250
16251    void backgroundServicesFinishedLocked(int userId) {
16252        for (BroadcastQueue queue : mBroadcastQueues) {
16253            queue.backgroundServicesFinishedLocked(userId);
16254        }
16255    }
16256
16257    public void finishReceiver(IBinder who, int resultCode, String resultData,
16258            Bundle resultExtras, boolean resultAbort) {
16259        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16260
16261        // Refuse possible leaked file descriptors
16262        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16263            throw new IllegalArgumentException("File descriptors passed in Bundle");
16264        }
16265
16266        final long origId = Binder.clearCallingIdentity();
16267        try {
16268            boolean doNext = false;
16269            BroadcastRecord r;
16270
16271            synchronized(this) {
16272                r = broadcastRecordForReceiverLocked(who);
16273                if (r != null) {
16274                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16275                        resultData, resultExtras, resultAbort, true);
16276                }
16277            }
16278
16279            if (doNext) {
16280                r.queue.processNextBroadcast(false);
16281            }
16282            trimApplications();
16283        } finally {
16284            Binder.restoreCallingIdentity(origId);
16285        }
16286    }
16287
16288    // =========================================================
16289    // INSTRUMENTATION
16290    // =========================================================
16291
16292    public boolean startInstrumentation(ComponentName className,
16293            String profileFile, int flags, Bundle arguments,
16294            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16295            int userId, String abiOverride) {
16296        enforceNotIsolatedCaller("startInstrumentation");
16297        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16298                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16299        // Refuse possible leaked file descriptors
16300        if (arguments != null && arguments.hasFileDescriptors()) {
16301            throw new IllegalArgumentException("File descriptors passed in Bundle");
16302        }
16303
16304        synchronized(this) {
16305            InstrumentationInfo ii = null;
16306            ApplicationInfo ai = null;
16307            try {
16308                ii = mContext.getPackageManager().getInstrumentationInfo(
16309                    className, STOCK_PM_FLAGS);
16310                ai = AppGlobals.getPackageManager().getApplicationInfo(
16311                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16312            } catch (PackageManager.NameNotFoundException e) {
16313            } catch (RemoteException e) {
16314            }
16315            if (ii == null) {
16316                reportStartInstrumentationFailure(watcher, className,
16317                        "Unable to find instrumentation info for: " + className);
16318                return false;
16319            }
16320            if (ai == null) {
16321                reportStartInstrumentationFailure(watcher, className,
16322                        "Unable to find instrumentation target package: " + ii.targetPackage);
16323                return false;
16324            }
16325
16326            int match = mContext.getPackageManager().checkSignatures(
16327                    ii.targetPackage, ii.packageName);
16328            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16329                String msg = "Permission Denial: starting instrumentation "
16330                        + className + " from pid="
16331                        + Binder.getCallingPid()
16332                        + ", uid=" + Binder.getCallingPid()
16333                        + " not allowed because package " + ii.packageName
16334                        + " does not have a signature matching the target "
16335                        + ii.targetPackage;
16336                reportStartInstrumentationFailure(watcher, className, msg);
16337                throw new SecurityException(msg);
16338            }
16339
16340            final long origId = Binder.clearCallingIdentity();
16341            // Instrumentation can kill and relaunch even persistent processes
16342            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16343                    "start instr");
16344            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16345            app.instrumentationClass = className;
16346            app.instrumentationInfo = ai;
16347            app.instrumentationProfileFile = profileFile;
16348            app.instrumentationArguments = arguments;
16349            app.instrumentationWatcher = watcher;
16350            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16351            app.instrumentationResultClass = className;
16352            Binder.restoreCallingIdentity(origId);
16353        }
16354
16355        return true;
16356    }
16357
16358    /**
16359     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16360     * error to the logs, but if somebody is watching, send the report there too.  This enables
16361     * the "am" command to report errors with more information.
16362     *
16363     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16364     * @param cn The component name of the instrumentation.
16365     * @param report The error report.
16366     */
16367    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16368            ComponentName cn, String report) {
16369        Slog.w(TAG, report);
16370        try {
16371            if (watcher != null) {
16372                Bundle results = new Bundle();
16373                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16374                results.putString("Error", report);
16375                watcher.instrumentationStatus(cn, -1, results);
16376            }
16377        } catch (RemoteException e) {
16378            Slog.w(TAG, e);
16379        }
16380    }
16381
16382    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16383        if (app.instrumentationWatcher != null) {
16384            try {
16385                // NOTE:  IInstrumentationWatcher *must* be oneway here
16386                app.instrumentationWatcher.instrumentationFinished(
16387                    app.instrumentationClass,
16388                    resultCode,
16389                    results);
16390            } catch (RemoteException e) {
16391            }
16392        }
16393        if (app.instrumentationUiAutomationConnection != null) {
16394            try {
16395                app.instrumentationUiAutomationConnection.shutdown();
16396            } catch (RemoteException re) {
16397                /* ignore */
16398            }
16399            // Only a UiAutomation can set this flag and now that
16400            // it is finished we make sure it is reset to its default.
16401            mUserIsMonkey = false;
16402        }
16403        app.instrumentationWatcher = null;
16404        app.instrumentationUiAutomationConnection = null;
16405        app.instrumentationClass = null;
16406        app.instrumentationInfo = null;
16407        app.instrumentationProfileFile = null;
16408        app.instrumentationArguments = null;
16409
16410        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16411                "finished inst");
16412    }
16413
16414    public void finishInstrumentation(IApplicationThread target,
16415            int resultCode, Bundle results) {
16416        int userId = UserHandle.getCallingUserId();
16417        // Refuse possible leaked file descriptors
16418        if (results != null && results.hasFileDescriptors()) {
16419            throw new IllegalArgumentException("File descriptors passed in Intent");
16420        }
16421
16422        synchronized(this) {
16423            ProcessRecord app = getRecordForAppLocked(target);
16424            if (app == null) {
16425                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16426                return;
16427            }
16428            final long origId = Binder.clearCallingIdentity();
16429            finishInstrumentationLocked(app, resultCode, results);
16430            Binder.restoreCallingIdentity(origId);
16431        }
16432    }
16433
16434    // =========================================================
16435    // CONFIGURATION
16436    // =========================================================
16437
16438    public ConfigurationInfo getDeviceConfigurationInfo() {
16439        ConfigurationInfo config = new ConfigurationInfo();
16440        synchronized (this) {
16441            config.reqTouchScreen = mConfiguration.touchscreen;
16442            config.reqKeyboardType = mConfiguration.keyboard;
16443            config.reqNavigation = mConfiguration.navigation;
16444            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16445                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16446                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16447            }
16448            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16449                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16450                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16451            }
16452            config.reqGlEsVersion = GL_ES_VERSION;
16453        }
16454        return config;
16455    }
16456
16457    ActivityStack getFocusedStack() {
16458        return mStackSupervisor.getFocusedStack();
16459    }
16460
16461    public Configuration getConfiguration() {
16462        Configuration ci;
16463        synchronized(this) {
16464            ci = new Configuration(mConfiguration);
16465        }
16466        return ci;
16467    }
16468
16469    public void updatePersistentConfiguration(Configuration values) {
16470        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16471                "updateConfiguration()");
16472        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16473                "updateConfiguration()");
16474        if (values == null) {
16475            throw new NullPointerException("Configuration must not be null");
16476        }
16477
16478        synchronized(this) {
16479            final long origId = Binder.clearCallingIdentity();
16480            updateConfigurationLocked(values, null, true, false);
16481            Binder.restoreCallingIdentity(origId);
16482        }
16483    }
16484
16485    public void updateConfiguration(Configuration values) {
16486        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16487                "updateConfiguration()");
16488
16489        synchronized(this) {
16490            if (values == null && mWindowManager != null) {
16491                // sentinel: fetch the current configuration from the window manager
16492                values = mWindowManager.computeNewConfiguration();
16493            }
16494
16495            if (mWindowManager != null) {
16496                mProcessList.applyDisplaySize(mWindowManager);
16497            }
16498
16499            final long origId = Binder.clearCallingIdentity();
16500            if (values != null) {
16501                Settings.System.clearConfiguration(values);
16502            }
16503            updateConfigurationLocked(values, null, false, false);
16504            Binder.restoreCallingIdentity(origId);
16505        }
16506    }
16507
16508    /**
16509     * Do either or both things: (1) change the current configuration, and (2)
16510     * make sure the given activity is running with the (now) current
16511     * configuration.  Returns true if the activity has been left running, or
16512     * false if <var>starting</var> is being destroyed to match the new
16513     * configuration.
16514     * @param persistent TODO
16515     */
16516    boolean updateConfigurationLocked(Configuration values,
16517            ActivityRecord starting, boolean persistent, boolean initLocale) {
16518        int changes = 0;
16519
16520        if (values != null) {
16521            Configuration newConfig = new Configuration(mConfiguration);
16522            changes = newConfig.updateFrom(values);
16523            if (changes != 0) {
16524                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16525                    Slog.i(TAG, "Updating configuration to: " + values);
16526                }
16527
16528                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16529
16530                if (values.locale != null && !initLocale) {
16531                    saveLocaleLocked(values.locale,
16532                                     !values.locale.equals(mConfiguration.locale),
16533                                     values.userSetLocale);
16534                }
16535
16536                mConfigurationSeq++;
16537                if (mConfigurationSeq <= 0) {
16538                    mConfigurationSeq = 1;
16539                }
16540                newConfig.seq = mConfigurationSeq;
16541                mConfiguration = newConfig;
16542                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16543                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16544                //mUsageStatsService.noteStartConfig(newConfig);
16545
16546                final Configuration configCopy = new Configuration(mConfiguration);
16547
16548                // TODO: If our config changes, should we auto dismiss any currently
16549                // showing dialogs?
16550                mShowDialogs = shouldShowDialogs(newConfig);
16551
16552                AttributeCache ac = AttributeCache.instance();
16553                if (ac != null) {
16554                    ac.updateConfiguration(configCopy);
16555                }
16556
16557                // Make sure all resources in our process are updated
16558                // right now, so that anyone who is going to retrieve
16559                // resource values after we return will be sure to get
16560                // the new ones.  This is especially important during
16561                // boot, where the first config change needs to guarantee
16562                // all resources have that config before following boot
16563                // code is executed.
16564                mSystemThread.applyConfigurationToResources(configCopy);
16565
16566                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16567                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16568                    msg.obj = new Configuration(configCopy);
16569                    mHandler.sendMessage(msg);
16570                }
16571
16572                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16573                    ProcessRecord app = mLruProcesses.get(i);
16574                    try {
16575                        if (app.thread != null) {
16576                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16577                                    + app.processName + " new config " + mConfiguration);
16578                            app.thread.scheduleConfigurationChanged(configCopy);
16579                        }
16580                    } catch (Exception e) {
16581                    }
16582                }
16583                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16584                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16585                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16586                        | Intent.FLAG_RECEIVER_FOREGROUND);
16587                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16588                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16589                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16590                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16591                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16592                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16593                    broadcastIntentLocked(null, null, intent,
16594                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16595                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16596                }
16597            }
16598        }
16599
16600        boolean kept = true;
16601        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16602        // mainStack is null during startup.
16603        if (mainStack != null) {
16604            if (changes != 0 && starting == null) {
16605                // If the configuration changed, and the caller is not already
16606                // in the process of starting an activity, then find the top
16607                // activity to check if its configuration needs to change.
16608                starting = mainStack.topRunningActivityLocked(null);
16609            }
16610
16611            if (starting != null) {
16612                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16613                // And we need to make sure at this point that all other activities
16614                // are made visible with the correct configuration.
16615                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16616            }
16617        }
16618
16619        if (values != null && mWindowManager != null) {
16620            mWindowManager.setNewConfiguration(mConfiguration);
16621        }
16622
16623        return kept;
16624    }
16625
16626    /**
16627     * Decide based on the configuration whether we should shouw the ANR,
16628     * crash, etc dialogs.  The idea is that if there is no affordnace to
16629     * press the on-screen buttons, we shouldn't show the dialog.
16630     *
16631     * A thought: SystemUI might also want to get told about this, the Power
16632     * dialog / global actions also might want different behaviors.
16633     */
16634    private static final boolean shouldShowDialogs(Configuration config) {
16635        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16636                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16637    }
16638
16639    /**
16640     * Save the locale.  You must be inside a synchronized (this) block.
16641     */
16642    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16643        if(isDiff) {
16644            SystemProperties.set("user.language", l.getLanguage());
16645            SystemProperties.set("user.region", l.getCountry());
16646        }
16647
16648        if(isPersist) {
16649            SystemProperties.set("persist.sys.language", l.getLanguage());
16650            SystemProperties.set("persist.sys.country", l.getCountry());
16651            SystemProperties.set("persist.sys.localevar", l.getVariant());
16652
16653            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16654        }
16655    }
16656
16657    @Override
16658    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16659        synchronized (this) {
16660            ActivityRecord srec = ActivityRecord.forToken(token);
16661            if (srec.task != null && srec.task.stack != null) {
16662                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16663            }
16664        }
16665        return false;
16666    }
16667
16668    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16669            Intent resultData) {
16670
16671        synchronized (this) {
16672            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16673            if (stack != null) {
16674                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16675            }
16676            return false;
16677        }
16678    }
16679
16680    public int getLaunchedFromUid(IBinder activityToken) {
16681        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16682        if (srec == null) {
16683            return -1;
16684        }
16685        return srec.launchedFromUid;
16686    }
16687
16688    public String getLaunchedFromPackage(IBinder activityToken) {
16689        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16690        if (srec == null) {
16691            return null;
16692        }
16693        return srec.launchedFromPackage;
16694    }
16695
16696    // =========================================================
16697    // LIFETIME MANAGEMENT
16698    // =========================================================
16699
16700    // Returns which broadcast queue the app is the current [or imminent] receiver
16701    // on, or 'null' if the app is not an active broadcast recipient.
16702    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16703        BroadcastRecord r = app.curReceiver;
16704        if (r != null) {
16705            return r.queue;
16706        }
16707
16708        // It's not the current receiver, but it might be starting up to become one
16709        synchronized (this) {
16710            for (BroadcastQueue queue : mBroadcastQueues) {
16711                r = queue.mPendingBroadcast;
16712                if (r != null && r.curApp == app) {
16713                    // found it; report which queue it's in
16714                    return queue;
16715                }
16716            }
16717        }
16718
16719        return null;
16720    }
16721
16722    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16723            boolean doingAll, long now) {
16724        if (mAdjSeq == app.adjSeq) {
16725            // This adjustment has already been computed.
16726            return app.curRawAdj;
16727        }
16728
16729        if (app.thread == null) {
16730            app.adjSeq = mAdjSeq;
16731            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16732            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16733            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16734        }
16735
16736        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16737        app.adjSource = null;
16738        app.adjTarget = null;
16739        app.empty = false;
16740        app.cached = false;
16741
16742        final int activitiesSize = app.activities.size();
16743
16744        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16745            // The max adjustment doesn't allow this app to be anything
16746            // below foreground, so it is not worth doing work for it.
16747            app.adjType = "fixed";
16748            app.adjSeq = mAdjSeq;
16749            app.curRawAdj = app.maxAdj;
16750            app.foregroundActivities = false;
16751            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16752            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16753            // System processes can do UI, and when they do we want to have
16754            // them trim their memory after the user leaves the UI.  To
16755            // facilitate this, here we need to determine whether or not it
16756            // is currently showing UI.
16757            app.systemNoUi = true;
16758            if (app == TOP_APP) {
16759                app.systemNoUi = false;
16760            } else if (activitiesSize > 0) {
16761                for (int j = 0; j < activitiesSize; j++) {
16762                    final ActivityRecord r = app.activities.get(j);
16763                    if (r.visible) {
16764                        app.systemNoUi = false;
16765                    }
16766                }
16767            }
16768            if (!app.systemNoUi) {
16769                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16770            }
16771            return (app.curAdj=app.maxAdj);
16772        }
16773
16774        app.systemNoUi = false;
16775
16776        // Determine the importance of the process, starting with most
16777        // important to least, and assign an appropriate OOM adjustment.
16778        int adj;
16779        int schedGroup;
16780        int procState;
16781        boolean foregroundActivities = false;
16782        BroadcastQueue queue;
16783        if (app == TOP_APP) {
16784            // The last app on the list is the foreground app.
16785            adj = ProcessList.FOREGROUND_APP_ADJ;
16786            schedGroup = Process.THREAD_GROUP_DEFAULT;
16787            app.adjType = "top-activity";
16788            foregroundActivities = true;
16789            procState = ActivityManager.PROCESS_STATE_TOP;
16790        } else if (app.instrumentationClass != null) {
16791            // Don't want to kill running instrumentation.
16792            adj = ProcessList.FOREGROUND_APP_ADJ;
16793            schedGroup = Process.THREAD_GROUP_DEFAULT;
16794            app.adjType = "instrumentation";
16795            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16796        } else if ((queue = isReceivingBroadcast(app)) != null) {
16797            // An app that is currently receiving a broadcast also
16798            // counts as being in the foreground for OOM killer purposes.
16799            // It's placed in a sched group based on the nature of the
16800            // broadcast as reflected by which queue it's active in.
16801            adj = ProcessList.FOREGROUND_APP_ADJ;
16802            schedGroup = (queue == mFgBroadcastQueue)
16803                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16804            app.adjType = "broadcast";
16805            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16806        } else if (app.executingServices.size() > 0) {
16807            // An app that is currently executing a service callback also
16808            // counts as being in the foreground.
16809            adj = ProcessList.FOREGROUND_APP_ADJ;
16810            schedGroup = app.execServicesFg ?
16811                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16812            app.adjType = "exec-service";
16813            procState = ActivityManager.PROCESS_STATE_SERVICE;
16814            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16815        } else {
16816            // As far as we know the process is empty.  We may change our mind later.
16817            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16818            // At this point we don't actually know the adjustment.  Use the cached adj
16819            // value that the caller wants us to.
16820            adj = cachedAdj;
16821            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16822            app.cached = true;
16823            app.empty = true;
16824            app.adjType = "cch-empty";
16825        }
16826
16827        // Examine all activities if not already foreground.
16828        if (!foregroundActivities && activitiesSize > 0) {
16829            for (int j = 0; j < activitiesSize; j++) {
16830                final ActivityRecord r = app.activities.get(j);
16831                if (r.app != app) {
16832                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16833                            + app + "?!?");
16834                    continue;
16835                }
16836                if (r.visible) {
16837                    // App has a visible activity; only upgrade adjustment.
16838                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16839                        adj = ProcessList.VISIBLE_APP_ADJ;
16840                        app.adjType = "visible";
16841                    }
16842                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16843                        procState = ActivityManager.PROCESS_STATE_TOP;
16844                    }
16845                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16846                    app.cached = false;
16847                    app.empty = false;
16848                    foregroundActivities = true;
16849                    break;
16850                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16851                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16852                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16853                        app.adjType = "pausing";
16854                    }
16855                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16856                        procState = ActivityManager.PROCESS_STATE_TOP;
16857                    }
16858                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16859                    app.cached = false;
16860                    app.empty = false;
16861                    foregroundActivities = true;
16862                } else if (r.state == ActivityState.STOPPING) {
16863                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16864                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16865                        app.adjType = "stopping";
16866                    }
16867                    // For the process state, we will at this point consider the
16868                    // process to be cached.  It will be cached either as an activity
16869                    // or empty depending on whether the activity is finishing.  We do
16870                    // this so that we can treat the process as cached for purposes of
16871                    // memory trimming (determing current memory level, trim command to
16872                    // send to process) since there can be an arbitrary number of stopping
16873                    // processes and they should soon all go into the cached state.
16874                    if (!r.finishing) {
16875                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16876                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16877                        }
16878                    }
16879                    app.cached = false;
16880                    app.empty = false;
16881                    foregroundActivities = true;
16882                } else {
16883                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16884                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16885                        app.adjType = "cch-act";
16886                    }
16887                }
16888            }
16889        }
16890
16891        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16892            if (app.foregroundServices) {
16893                // The user is aware of this app, so make it visible.
16894                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16895                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16896                app.cached = false;
16897                app.adjType = "fg-service";
16898                schedGroup = Process.THREAD_GROUP_DEFAULT;
16899            } else if (app.forcingToForeground != null) {
16900                // The user is aware of this app, so make it visible.
16901                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16902                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16903                app.cached = false;
16904                app.adjType = "force-fg";
16905                app.adjSource = app.forcingToForeground;
16906                schedGroup = Process.THREAD_GROUP_DEFAULT;
16907            }
16908        }
16909
16910        if (app == mHeavyWeightProcess) {
16911            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16912                // We don't want to kill the current heavy-weight process.
16913                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16914                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16915                app.cached = false;
16916                app.adjType = "heavy";
16917            }
16918            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16919                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16920            }
16921        }
16922
16923        if (app == mHomeProcess) {
16924            if (adj > ProcessList.HOME_APP_ADJ) {
16925                // This process is hosting what we currently consider to be the
16926                // home app, so we don't want to let it go into the background.
16927                adj = ProcessList.HOME_APP_ADJ;
16928                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16929                app.cached = false;
16930                app.adjType = "home";
16931            }
16932            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16933                procState = ActivityManager.PROCESS_STATE_HOME;
16934            }
16935        }
16936
16937        if (app == mPreviousProcess && app.activities.size() > 0) {
16938            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16939                // This was the previous process that showed UI to the user.
16940                // We want to try to keep it around more aggressively, to give
16941                // a good experience around switching between two apps.
16942                adj = ProcessList.PREVIOUS_APP_ADJ;
16943                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16944                app.cached = false;
16945                app.adjType = "previous";
16946            }
16947            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16948                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16949            }
16950        }
16951
16952        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16953                + " reason=" + app.adjType);
16954
16955        // By default, we use the computed adjustment.  It may be changed if
16956        // there are applications dependent on our services or providers, but
16957        // this gives us a baseline and makes sure we don't get into an
16958        // infinite recursion.
16959        app.adjSeq = mAdjSeq;
16960        app.curRawAdj = adj;
16961        app.hasStartedServices = false;
16962
16963        if (mBackupTarget != null && app == mBackupTarget.app) {
16964            // If possible we want to avoid killing apps while they're being backed up
16965            if (adj > ProcessList.BACKUP_APP_ADJ) {
16966                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16967                adj = ProcessList.BACKUP_APP_ADJ;
16968                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16969                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16970                }
16971                app.adjType = "backup";
16972                app.cached = false;
16973            }
16974            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16975                procState = ActivityManager.PROCESS_STATE_BACKUP;
16976            }
16977        }
16978
16979        boolean mayBeTop = false;
16980
16981        for (int is = app.services.size()-1;
16982                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16983                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16984                        || procState > ActivityManager.PROCESS_STATE_TOP);
16985                is--) {
16986            ServiceRecord s = app.services.valueAt(is);
16987            if (s.startRequested) {
16988                app.hasStartedServices = true;
16989                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16990                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16991                }
16992                if (app.hasShownUi && app != mHomeProcess) {
16993                    // If this process has shown some UI, let it immediately
16994                    // go to the LRU list because it may be pretty heavy with
16995                    // UI stuff.  We'll tag it with a label just to help
16996                    // debug and understand what is going on.
16997                    if (adj > ProcessList.SERVICE_ADJ) {
16998                        app.adjType = "cch-started-ui-services";
16999                    }
17000                } else {
17001                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17002                        // This service has seen some activity within
17003                        // recent memory, so we will keep its process ahead
17004                        // of the background processes.
17005                        if (adj > ProcessList.SERVICE_ADJ) {
17006                            adj = ProcessList.SERVICE_ADJ;
17007                            app.adjType = "started-services";
17008                            app.cached = false;
17009                        }
17010                    }
17011                    // If we have let the service slide into the background
17012                    // state, still have some text describing what it is doing
17013                    // even though the service no longer has an impact.
17014                    if (adj > ProcessList.SERVICE_ADJ) {
17015                        app.adjType = "cch-started-services";
17016                    }
17017                }
17018            }
17019            for (int conni = s.connections.size()-1;
17020                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17021                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17022                            || procState > ActivityManager.PROCESS_STATE_TOP);
17023                    conni--) {
17024                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17025                for (int i = 0;
17026                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17027                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17028                                || procState > ActivityManager.PROCESS_STATE_TOP);
17029                        i++) {
17030                    // XXX should compute this based on the max of
17031                    // all connected clients.
17032                    ConnectionRecord cr = clist.get(i);
17033                    if (cr.binding.client == app) {
17034                        // Binding to ourself is not interesting.
17035                        continue;
17036                    }
17037                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17038                        ProcessRecord client = cr.binding.client;
17039                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17040                                TOP_APP, doingAll, now);
17041                        int clientProcState = client.curProcState;
17042                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17043                            // If the other app is cached for any reason, for purposes here
17044                            // we are going to consider it empty.  The specific cached state
17045                            // doesn't propagate except under certain conditions.
17046                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17047                        }
17048                        String adjType = null;
17049                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17050                            // Not doing bind OOM management, so treat
17051                            // this guy more like a started service.
17052                            if (app.hasShownUi && app != mHomeProcess) {
17053                                // If this process has shown some UI, let it immediately
17054                                // go to the LRU list because it may be pretty heavy with
17055                                // UI stuff.  We'll tag it with a label just to help
17056                                // debug and understand what is going on.
17057                                if (adj > clientAdj) {
17058                                    adjType = "cch-bound-ui-services";
17059                                }
17060                                app.cached = false;
17061                                clientAdj = adj;
17062                                clientProcState = procState;
17063                            } else {
17064                                if (now >= (s.lastActivity
17065                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17066                                    // This service has not seen activity within
17067                                    // recent memory, so allow it to drop to the
17068                                    // LRU list if there is no other reason to keep
17069                                    // it around.  We'll also tag it with a label just
17070                                    // to help debug and undertand what is going on.
17071                                    if (adj > clientAdj) {
17072                                        adjType = "cch-bound-services";
17073                                    }
17074                                    clientAdj = adj;
17075                                }
17076                            }
17077                        }
17078                        if (adj > clientAdj) {
17079                            // If this process has recently shown UI, and
17080                            // the process that is binding to it is less
17081                            // important than being visible, then we don't
17082                            // care about the binding as much as we care
17083                            // about letting this process get into the LRU
17084                            // list to be killed and restarted if needed for
17085                            // memory.
17086                            if (app.hasShownUi && app != mHomeProcess
17087                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17088                                adjType = "cch-bound-ui-services";
17089                            } else {
17090                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17091                                        |Context.BIND_IMPORTANT)) != 0) {
17092                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17093                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17094                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17095                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17096                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17097                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17098                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17099                                    adj = clientAdj;
17100                                } else {
17101                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17102                                        adj = ProcessList.VISIBLE_APP_ADJ;
17103                                    }
17104                                }
17105                                if (!client.cached) {
17106                                    app.cached = false;
17107                                }
17108                                adjType = "service";
17109                            }
17110                        }
17111                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17112                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17113                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17114                            }
17115                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17116                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17117                                    // Special handling of clients who are in the top state.
17118                                    // We *may* want to consider this process to be in the
17119                                    // top state as well, but only if there is not another
17120                                    // reason for it to be running.  Being on the top is a
17121                                    // special state, meaning you are specifically running
17122                                    // for the current top app.  If the process is already
17123                                    // running in the background for some other reason, it
17124                                    // is more important to continue considering it to be
17125                                    // in the background state.
17126                                    mayBeTop = true;
17127                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17128                                } else {
17129                                    // Special handling for above-top states (persistent
17130                                    // processes).  These should not bring the current process
17131                                    // into the top state, since they are not on top.  Instead
17132                                    // give them the best state after that.
17133                                    clientProcState =
17134                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17135                                }
17136                            }
17137                        } else {
17138                            if (clientProcState <
17139                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17140                                clientProcState =
17141                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17142                            }
17143                        }
17144                        if (procState > clientProcState) {
17145                            procState = clientProcState;
17146                        }
17147                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17148                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17149                            app.pendingUiClean = true;
17150                        }
17151                        if (adjType != null) {
17152                            app.adjType = adjType;
17153                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17154                                    .REASON_SERVICE_IN_USE;
17155                            app.adjSource = cr.binding.client;
17156                            app.adjSourceProcState = clientProcState;
17157                            app.adjTarget = s.name;
17158                        }
17159                    }
17160                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17161                        app.treatLikeActivity = true;
17162                    }
17163                    final ActivityRecord a = cr.activity;
17164                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17165                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17166                                (a.visible || a.state == ActivityState.RESUMED
17167                                 || a.state == ActivityState.PAUSING)) {
17168                            adj = ProcessList.FOREGROUND_APP_ADJ;
17169                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17170                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17171                            }
17172                            app.cached = false;
17173                            app.adjType = "service";
17174                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17175                                    .REASON_SERVICE_IN_USE;
17176                            app.adjSource = a;
17177                            app.adjSourceProcState = procState;
17178                            app.adjTarget = s.name;
17179                        }
17180                    }
17181                }
17182            }
17183        }
17184
17185        for (int provi = app.pubProviders.size()-1;
17186                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17187                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17188                        || procState > ActivityManager.PROCESS_STATE_TOP);
17189                provi--) {
17190            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17191            for (int i = cpr.connections.size()-1;
17192                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17193                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17194                            || procState > ActivityManager.PROCESS_STATE_TOP);
17195                    i--) {
17196                ContentProviderConnection conn = cpr.connections.get(i);
17197                ProcessRecord client = conn.client;
17198                if (client == app) {
17199                    // Being our own client is not interesting.
17200                    continue;
17201                }
17202                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17203                int clientProcState = client.curProcState;
17204                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17205                    // If the other app is cached for any reason, for purposes here
17206                    // we are going to consider it empty.
17207                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17208                }
17209                if (adj > clientAdj) {
17210                    if (app.hasShownUi && app != mHomeProcess
17211                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17212                        app.adjType = "cch-ui-provider";
17213                    } else {
17214                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17215                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17216                        app.adjType = "provider";
17217                    }
17218                    app.cached &= client.cached;
17219                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17220                            .REASON_PROVIDER_IN_USE;
17221                    app.adjSource = client;
17222                    app.adjSourceProcState = clientProcState;
17223                    app.adjTarget = cpr.name;
17224                }
17225                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17226                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17227                        // Special handling of clients who are in the top state.
17228                        // We *may* want to consider this process to be in the
17229                        // top state as well, but only if there is not another
17230                        // reason for it to be running.  Being on the top is a
17231                        // special state, meaning you are specifically running
17232                        // for the current top app.  If the process is already
17233                        // running in the background for some other reason, it
17234                        // is more important to continue considering it to be
17235                        // in the background state.
17236                        mayBeTop = true;
17237                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17238                    } else {
17239                        // Special handling for above-top states (persistent
17240                        // processes).  These should not bring the current process
17241                        // into the top state, since they are not on top.  Instead
17242                        // give them the best state after that.
17243                        clientProcState =
17244                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17245                    }
17246                }
17247                if (procState > clientProcState) {
17248                    procState = clientProcState;
17249                }
17250                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17251                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17252                }
17253            }
17254            // If the provider has external (non-framework) process
17255            // dependencies, ensure that its adjustment is at least
17256            // FOREGROUND_APP_ADJ.
17257            if (cpr.hasExternalProcessHandles()) {
17258                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17259                    adj = ProcessList.FOREGROUND_APP_ADJ;
17260                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17261                    app.cached = false;
17262                    app.adjType = "provider";
17263                    app.adjTarget = cpr.name;
17264                }
17265                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17266                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17267                }
17268            }
17269        }
17270
17271        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17272            // A client of one of our services or providers is in the top state.  We
17273            // *may* want to be in the top state, but not if we are already running in
17274            // the background for some other reason.  For the decision here, we are going
17275            // to pick out a few specific states that we want to remain in when a client
17276            // is top (states that tend to be longer-term) and otherwise allow it to go
17277            // to the top state.
17278            switch (procState) {
17279                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17280                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17281                case ActivityManager.PROCESS_STATE_SERVICE:
17282                    // These all are longer-term states, so pull them up to the top
17283                    // of the background states, but not all the way to the top state.
17284                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17285                    break;
17286                default:
17287                    // Otherwise, top is a better choice, so take it.
17288                    procState = ActivityManager.PROCESS_STATE_TOP;
17289                    break;
17290            }
17291        }
17292
17293        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17294            if (app.hasClientActivities) {
17295                // This is a cached process, but with client activities.  Mark it so.
17296                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17297                app.adjType = "cch-client-act";
17298            } else if (app.treatLikeActivity) {
17299                // This is a cached process, but somebody wants us to treat it like it has
17300                // an activity, okay!
17301                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17302                app.adjType = "cch-as-act";
17303            }
17304        }
17305
17306        if (adj == ProcessList.SERVICE_ADJ) {
17307            if (doingAll) {
17308                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17309                mNewNumServiceProcs++;
17310                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17311                if (!app.serviceb) {
17312                    // This service isn't far enough down on the LRU list to
17313                    // normally be a B service, but if we are low on RAM and it
17314                    // is large we want to force it down since we would prefer to
17315                    // keep launcher over it.
17316                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17317                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17318                        app.serviceHighRam = true;
17319                        app.serviceb = true;
17320                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17321                    } else {
17322                        mNewNumAServiceProcs++;
17323                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17324                    }
17325                } else {
17326                    app.serviceHighRam = false;
17327                }
17328            }
17329            if (app.serviceb) {
17330                adj = ProcessList.SERVICE_B_ADJ;
17331            }
17332        }
17333
17334        app.curRawAdj = adj;
17335
17336        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17337        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17338        if (adj > app.maxAdj) {
17339            adj = app.maxAdj;
17340            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17341                schedGroup = Process.THREAD_GROUP_DEFAULT;
17342            }
17343        }
17344
17345        // Do final modification to adj.  Everything we do between here and applying
17346        // the final setAdj must be done in this function, because we will also use
17347        // it when computing the final cached adj later.  Note that we don't need to
17348        // worry about this for max adj above, since max adj will always be used to
17349        // keep it out of the cached vaues.
17350        app.curAdj = app.modifyRawOomAdj(adj);
17351        app.curSchedGroup = schedGroup;
17352        app.curProcState = procState;
17353        app.foregroundActivities = foregroundActivities;
17354
17355        return app.curRawAdj;
17356    }
17357
17358    /**
17359     * Record new PSS sample for a process.
17360     */
17361    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17362        proc.lastPssTime = now;
17363        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17364        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17365                + ": " + pss + " lastPss=" + proc.lastPss
17366                + " state=" + ProcessList.makeProcStateString(procState));
17367        if (proc.initialIdlePss == 0) {
17368            proc.initialIdlePss = pss;
17369        }
17370        proc.lastPss = pss;
17371        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17372            proc.lastCachedPss = pss;
17373        }
17374    }
17375
17376    /**
17377     * Schedule PSS collection of a process.
17378     */
17379    void requestPssLocked(ProcessRecord proc, int procState) {
17380        if (mPendingPssProcesses.contains(proc)) {
17381            return;
17382        }
17383        if (mPendingPssProcesses.size() == 0) {
17384            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17385        }
17386        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17387        proc.pssProcState = procState;
17388        mPendingPssProcesses.add(proc);
17389    }
17390
17391    /**
17392     * Schedule PSS collection of all processes.
17393     */
17394    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17395        if (!always) {
17396            if (now < (mLastFullPssTime +
17397                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17398                return;
17399            }
17400        }
17401        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17402        mLastFullPssTime = now;
17403        mFullPssPending = true;
17404        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17405        mPendingPssProcesses.clear();
17406        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17407            ProcessRecord app = mLruProcesses.get(i);
17408            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17409                app.pssProcState = app.setProcState;
17410                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17411                        mTestPssMode, isSleeping(), now);
17412                mPendingPssProcesses.add(app);
17413            }
17414        }
17415        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17416    }
17417
17418    public void setTestPssMode(boolean enabled) {
17419        synchronized (this) {
17420            mTestPssMode = enabled;
17421            if (enabled) {
17422                // Whenever we enable the mode, we want to take a snapshot all of current
17423                // process mem use.
17424                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17425            }
17426        }
17427    }
17428
17429    /**
17430     * Ask a given process to GC right now.
17431     */
17432    final void performAppGcLocked(ProcessRecord app) {
17433        try {
17434            app.lastRequestedGc = SystemClock.uptimeMillis();
17435            if (app.thread != null) {
17436                if (app.reportLowMemory) {
17437                    app.reportLowMemory = false;
17438                    app.thread.scheduleLowMemory();
17439                } else {
17440                    app.thread.processInBackground();
17441                }
17442            }
17443        } catch (Exception e) {
17444            // whatever.
17445        }
17446    }
17447
17448    /**
17449     * Returns true if things are idle enough to perform GCs.
17450     */
17451    private final boolean canGcNowLocked() {
17452        boolean processingBroadcasts = false;
17453        for (BroadcastQueue q : mBroadcastQueues) {
17454            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17455                processingBroadcasts = true;
17456            }
17457        }
17458        return !processingBroadcasts
17459                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17460    }
17461
17462    /**
17463     * Perform GCs on all processes that are waiting for it, but only
17464     * if things are idle.
17465     */
17466    final void performAppGcsLocked() {
17467        final int N = mProcessesToGc.size();
17468        if (N <= 0) {
17469            return;
17470        }
17471        if (canGcNowLocked()) {
17472            while (mProcessesToGc.size() > 0) {
17473                ProcessRecord proc = mProcessesToGc.remove(0);
17474                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17475                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17476                            <= SystemClock.uptimeMillis()) {
17477                        // To avoid spamming the system, we will GC processes one
17478                        // at a time, waiting a few seconds between each.
17479                        performAppGcLocked(proc);
17480                        scheduleAppGcsLocked();
17481                        return;
17482                    } else {
17483                        // It hasn't been long enough since we last GCed this
17484                        // process...  put it in the list to wait for its time.
17485                        addProcessToGcListLocked(proc);
17486                        break;
17487                    }
17488                }
17489            }
17490
17491            scheduleAppGcsLocked();
17492        }
17493    }
17494
17495    /**
17496     * If all looks good, perform GCs on all processes waiting for them.
17497     */
17498    final void performAppGcsIfAppropriateLocked() {
17499        if (canGcNowLocked()) {
17500            performAppGcsLocked();
17501            return;
17502        }
17503        // Still not idle, wait some more.
17504        scheduleAppGcsLocked();
17505    }
17506
17507    /**
17508     * Schedule the execution of all pending app GCs.
17509     */
17510    final void scheduleAppGcsLocked() {
17511        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17512
17513        if (mProcessesToGc.size() > 0) {
17514            // Schedule a GC for the time to the next process.
17515            ProcessRecord proc = mProcessesToGc.get(0);
17516            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17517
17518            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17519            long now = SystemClock.uptimeMillis();
17520            if (when < (now+GC_TIMEOUT)) {
17521                when = now + GC_TIMEOUT;
17522            }
17523            mHandler.sendMessageAtTime(msg, when);
17524        }
17525    }
17526
17527    /**
17528     * Add a process to the array of processes waiting to be GCed.  Keeps the
17529     * list in sorted order by the last GC time.  The process can't already be
17530     * on the list.
17531     */
17532    final void addProcessToGcListLocked(ProcessRecord proc) {
17533        boolean added = false;
17534        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17535            if (mProcessesToGc.get(i).lastRequestedGc <
17536                    proc.lastRequestedGc) {
17537                added = true;
17538                mProcessesToGc.add(i+1, proc);
17539                break;
17540            }
17541        }
17542        if (!added) {
17543            mProcessesToGc.add(0, proc);
17544        }
17545    }
17546
17547    /**
17548     * Set up to ask a process to GC itself.  This will either do it
17549     * immediately, or put it on the list of processes to gc the next
17550     * time things are idle.
17551     */
17552    final void scheduleAppGcLocked(ProcessRecord app) {
17553        long now = SystemClock.uptimeMillis();
17554        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17555            return;
17556        }
17557        if (!mProcessesToGc.contains(app)) {
17558            addProcessToGcListLocked(app);
17559            scheduleAppGcsLocked();
17560        }
17561    }
17562
17563    final void checkExcessivePowerUsageLocked(boolean doKills) {
17564        updateCpuStatsNow();
17565
17566        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17567        boolean doWakeKills = doKills;
17568        boolean doCpuKills = doKills;
17569        if (mLastPowerCheckRealtime == 0) {
17570            doWakeKills = false;
17571        }
17572        if (mLastPowerCheckUptime == 0) {
17573            doCpuKills = false;
17574        }
17575        if (stats.isScreenOn()) {
17576            doWakeKills = false;
17577        }
17578        final long curRealtime = SystemClock.elapsedRealtime();
17579        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17580        final long curUptime = SystemClock.uptimeMillis();
17581        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17582        mLastPowerCheckRealtime = curRealtime;
17583        mLastPowerCheckUptime = curUptime;
17584        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17585            doWakeKills = false;
17586        }
17587        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17588            doCpuKills = false;
17589        }
17590        int i = mLruProcesses.size();
17591        while (i > 0) {
17592            i--;
17593            ProcessRecord app = mLruProcesses.get(i);
17594            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17595                long wtime;
17596                synchronized (stats) {
17597                    wtime = stats.getProcessWakeTime(app.info.uid,
17598                            app.pid, curRealtime);
17599                }
17600                long wtimeUsed = wtime - app.lastWakeTime;
17601                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17602                if (DEBUG_POWER) {
17603                    StringBuilder sb = new StringBuilder(128);
17604                    sb.append("Wake for ");
17605                    app.toShortString(sb);
17606                    sb.append(": over ");
17607                    TimeUtils.formatDuration(realtimeSince, sb);
17608                    sb.append(" used ");
17609                    TimeUtils.formatDuration(wtimeUsed, sb);
17610                    sb.append(" (");
17611                    sb.append((wtimeUsed*100)/realtimeSince);
17612                    sb.append("%)");
17613                    Slog.i(TAG, sb.toString());
17614                    sb.setLength(0);
17615                    sb.append("CPU for ");
17616                    app.toShortString(sb);
17617                    sb.append(": over ");
17618                    TimeUtils.formatDuration(uptimeSince, sb);
17619                    sb.append(" used ");
17620                    TimeUtils.formatDuration(cputimeUsed, sb);
17621                    sb.append(" (");
17622                    sb.append((cputimeUsed*100)/uptimeSince);
17623                    sb.append("%)");
17624                    Slog.i(TAG, sb.toString());
17625                }
17626                // If a process has held a wake lock for more
17627                // than 50% of the time during this period,
17628                // that sounds bad.  Kill!
17629                if (doWakeKills && realtimeSince > 0
17630                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17631                    synchronized (stats) {
17632                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17633                                realtimeSince, wtimeUsed);
17634                    }
17635                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17636                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17637                } else if (doCpuKills && uptimeSince > 0
17638                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17639                    synchronized (stats) {
17640                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17641                                uptimeSince, cputimeUsed);
17642                    }
17643                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17644                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17645                } else {
17646                    app.lastWakeTime = wtime;
17647                    app.lastCpuTime = app.curCpuTime;
17648                }
17649            }
17650        }
17651    }
17652
17653    private final boolean applyOomAdjLocked(ProcessRecord app,
17654            ProcessRecord TOP_APP, boolean doingAll, long now) {
17655        boolean success = true;
17656
17657        if (app.curRawAdj != app.setRawAdj) {
17658            app.setRawAdj = app.curRawAdj;
17659        }
17660
17661        int changes = 0;
17662
17663        if (app.curAdj != app.setAdj) {
17664            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17665            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17666                TAG, "Set " + app.pid + " " + app.processName +
17667                " adj " + app.curAdj + ": " + app.adjType);
17668            app.setAdj = app.curAdj;
17669        }
17670
17671        if (app.setSchedGroup != app.curSchedGroup) {
17672            app.setSchedGroup = app.curSchedGroup;
17673            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17674                    "Setting process group of " + app.processName
17675                    + " to " + app.curSchedGroup);
17676            if (app.waitingToKill != null &&
17677                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17678                app.kill(app.waitingToKill, true);
17679                success = false;
17680            } else {
17681                if (true) {
17682                    long oldId = Binder.clearCallingIdentity();
17683                    try {
17684                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17685                    } catch (Exception e) {
17686                        Slog.w(TAG, "Failed setting process group of " + app.pid
17687                                + " to " + app.curSchedGroup);
17688                        e.printStackTrace();
17689                    } finally {
17690                        Binder.restoreCallingIdentity(oldId);
17691                    }
17692                } else {
17693                    if (app.thread != null) {
17694                        try {
17695                            app.thread.setSchedulingGroup(app.curSchedGroup);
17696                        } catch (RemoteException e) {
17697                        }
17698                    }
17699                }
17700                Process.setSwappiness(app.pid,
17701                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17702            }
17703        }
17704        if (app.repForegroundActivities != app.foregroundActivities) {
17705            app.repForegroundActivities = app.foregroundActivities;
17706            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17707        }
17708        if (app.repProcState != app.curProcState) {
17709            app.repProcState = app.curProcState;
17710            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17711            if (app.thread != null) {
17712                try {
17713                    if (false) {
17714                        //RuntimeException h = new RuntimeException("here");
17715                        Slog.i(TAG, "Sending new process state " + app.repProcState
17716                                + " to " + app /*, h*/);
17717                    }
17718                    app.thread.setProcessState(app.repProcState);
17719                } catch (RemoteException e) {
17720                }
17721            }
17722        }
17723        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17724                app.setProcState)) {
17725            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17726                // Experimental code to more aggressively collect pss while
17727                // running test...  the problem is that this tends to collect
17728                // the data right when a process is transitioning between process
17729                // states, which well tend to give noisy data.
17730                long start = SystemClock.uptimeMillis();
17731                long pss = Debug.getPss(app.pid, mTmpLong, null);
17732                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17733                mPendingPssProcesses.remove(app);
17734                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17735                        + " to " + app.curProcState + ": "
17736                        + (SystemClock.uptimeMillis()-start) + "ms");
17737            }
17738            app.lastStateTime = now;
17739            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17740                    mTestPssMode, isSleeping(), now);
17741            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17742                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17743                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17744                    + (app.nextPssTime-now) + ": " + app);
17745        } else {
17746            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17747                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17748                requestPssLocked(app, app.setProcState);
17749                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17750                        mTestPssMode, isSleeping(), now);
17751            } else if (false && DEBUG_PSS) {
17752                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17753            }
17754        }
17755        if (app.setProcState != app.curProcState) {
17756            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17757                    "Proc state change of " + app.processName
17758                    + " to " + app.curProcState);
17759            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17760            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17761            if (setImportant && !curImportant) {
17762                // This app is no longer something we consider important enough to allow to
17763                // use arbitrary amounts of battery power.  Note
17764                // its current wake lock time to later know to kill it if
17765                // it is not behaving well.
17766                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17767                synchronized (stats) {
17768                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17769                            app.pid, SystemClock.elapsedRealtime());
17770                }
17771                app.lastCpuTime = app.curCpuTime;
17772
17773            }
17774            app.setProcState = app.curProcState;
17775            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17776                app.notCachedSinceIdle = false;
17777            }
17778            if (!doingAll) {
17779                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17780            } else {
17781                app.procStateChanged = true;
17782            }
17783        }
17784
17785        if (changes != 0) {
17786            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17787            int i = mPendingProcessChanges.size()-1;
17788            ProcessChangeItem item = null;
17789            while (i >= 0) {
17790                item = mPendingProcessChanges.get(i);
17791                if (item.pid == app.pid) {
17792                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17793                    break;
17794                }
17795                i--;
17796            }
17797            if (i < 0) {
17798                // No existing item in pending changes; need a new one.
17799                final int NA = mAvailProcessChanges.size();
17800                if (NA > 0) {
17801                    item = mAvailProcessChanges.remove(NA-1);
17802                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17803                } else {
17804                    item = new ProcessChangeItem();
17805                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17806                }
17807                item.changes = 0;
17808                item.pid = app.pid;
17809                item.uid = app.info.uid;
17810                if (mPendingProcessChanges.size() == 0) {
17811                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17812                            "*** Enqueueing dispatch processes changed!");
17813                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17814                }
17815                mPendingProcessChanges.add(item);
17816            }
17817            item.changes |= changes;
17818            item.processState = app.repProcState;
17819            item.foregroundActivities = app.repForegroundActivities;
17820            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17821                    + Integer.toHexString(System.identityHashCode(item))
17822                    + " " + app.toShortString() + ": changes=" + item.changes
17823                    + " procState=" + item.processState
17824                    + " foreground=" + item.foregroundActivities
17825                    + " type=" + app.adjType + " source=" + app.adjSource
17826                    + " target=" + app.adjTarget);
17827        }
17828
17829        return success;
17830    }
17831
17832    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17833        if (proc.thread != null) {
17834            if (proc.baseProcessTracker != null) {
17835                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17836            }
17837            if (proc.repProcState >= 0) {
17838                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17839                        proc.repProcState);
17840            }
17841        }
17842    }
17843
17844    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17845            ProcessRecord TOP_APP, boolean doingAll, long now) {
17846        if (app.thread == null) {
17847            return false;
17848        }
17849
17850        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17851
17852        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17853    }
17854
17855    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17856            boolean oomAdj) {
17857        if (isForeground != proc.foregroundServices) {
17858            proc.foregroundServices = isForeground;
17859            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17860                    proc.info.uid);
17861            if (isForeground) {
17862                if (curProcs == null) {
17863                    curProcs = new ArrayList<ProcessRecord>();
17864                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17865                }
17866                if (!curProcs.contains(proc)) {
17867                    curProcs.add(proc);
17868                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17869                            proc.info.packageName, proc.info.uid);
17870                }
17871            } else {
17872                if (curProcs != null) {
17873                    if (curProcs.remove(proc)) {
17874                        mBatteryStatsService.noteEvent(
17875                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17876                                proc.info.packageName, proc.info.uid);
17877                        if (curProcs.size() <= 0) {
17878                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17879                        }
17880                    }
17881                }
17882            }
17883            if (oomAdj) {
17884                updateOomAdjLocked();
17885            }
17886        }
17887    }
17888
17889    private final ActivityRecord resumedAppLocked() {
17890        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17891        String pkg;
17892        int uid;
17893        if (act != null) {
17894            pkg = act.packageName;
17895            uid = act.info.applicationInfo.uid;
17896        } else {
17897            pkg = null;
17898            uid = -1;
17899        }
17900        // Has the UID or resumed package name changed?
17901        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17902                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17903            if (mCurResumedPackage != null) {
17904                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17905                        mCurResumedPackage, mCurResumedUid);
17906            }
17907            mCurResumedPackage = pkg;
17908            mCurResumedUid = uid;
17909            if (mCurResumedPackage != null) {
17910                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17911                        mCurResumedPackage, mCurResumedUid);
17912            }
17913        }
17914        return act;
17915    }
17916
17917    final boolean updateOomAdjLocked(ProcessRecord app) {
17918        final ActivityRecord TOP_ACT = resumedAppLocked();
17919        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17920        final boolean wasCached = app.cached;
17921
17922        mAdjSeq++;
17923
17924        // This is the desired cached adjusment we want to tell it to use.
17925        // If our app is currently cached, we know it, and that is it.  Otherwise,
17926        // we don't know it yet, and it needs to now be cached we will then
17927        // need to do a complete oom adj.
17928        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17929                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17930        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17931                SystemClock.uptimeMillis());
17932        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17933            // Changed to/from cached state, so apps after it in the LRU
17934            // list may also be changed.
17935            updateOomAdjLocked();
17936        }
17937        return success;
17938    }
17939
17940    final void updateOomAdjLocked() {
17941        final ActivityRecord TOP_ACT = resumedAppLocked();
17942        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17943        final long now = SystemClock.uptimeMillis();
17944        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17945        final int N = mLruProcesses.size();
17946
17947        if (false) {
17948            RuntimeException e = new RuntimeException();
17949            e.fillInStackTrace();
17950            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17951        }
17952
17953        mAdjSeq++;
17954        mNewNumServiceProcs = 0;
17955        mNewNumAServiceProcs = 0;
17956
17957        final int emptyProcessLimit;
17958        final int cachedProcessLimit;
17959        if (mProcessLimit <= 0) {
17960            emptyProcessLimit = cachedProcessLimit = 0;
17961        } else if (mProcessLimit == 1) {
17962            emptyProcessLimit = 1;
17963            cachedProcessLimit = 0;
17964        } else {
17965            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17966            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17967        }
17968
17969        // Let's determine how many processes we have running vs.
17970        // how many slots we have for background processes; we may want
17971        // to put multiple processes in a slot of there are enough of
17972        // them.
17973        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17974                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17975        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17976        if (numEmptyProcs > cachedProcessLimit) {
17977            // If there are more empty processes than our limit on cached
17978            // processes, then use the cached process limit for the factor.
17979            // This ensures that the really old empty processes get pushed
17980            // down to the bottom, so if we are running low on memory we will
17981            // have a better chance at keeping around more cached processes
17982            // instead of a gazillion empty processes.
17983            numEmptyProcs = cachedProcessLimit;
17984        }
17985        int emptyFactor = numEmptyProcs/numSlots;
17986        if (emptyFactor < 1) emptyFactor = 1;
17987        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17988        if (cachedFactor < 1) cachedFactor = 1;
17989        int stepCached = 0;
17990        int stepEmpty = 0;
17991        int numCached = 0;
17992        int numEmpty = 0;
17993        int numTrimming = 0;
17994
17995        mNumNonCachedProcs = 0;
17996        mNumCachedHiddenProcs = 0;
17997
17998        // First update the OOM adjustment for each of the
17999        // application processes based on their current state.
18000        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18001        int nextCachedAdj = curCachedAdj+1;
18002        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18003        int nextEmptyAdj = curEmptyAdj+2;
18004        for (int i=N-1; i>=0; i--) {
18005            ProcessRecord app = mLruProcesses.get(i);
18006            if (!app.killedByAm && app.thread != null) {
18007                app.procStateChanged = false;
18008                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18009
18010                // If we haven't yet assigned the final cached adj
18011                // to the process, do that now.
18012                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18013                    switch (app.curProcState) {
18014                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18015                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18016                            // This process is a cached process holding activities...
18017                            // assign it the next cached value for that type, and then
18018                            // step that cached level.
18019                            app.curRawAdj = curCachedAdj;
18020                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18021                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18022                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18023                                    + ")");
18024                            if (curCachedAdj != nextCachedAdj) {
18025                                stepCached++;
18026                                if (stepCached >= cachedFactor) {
18027                                    stepCached = 0;
18028                                    curCachedAdj = nextCachedAdj;
18029                                    nextCachedAdj += 2;
18030                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18031                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18032                                    }
18033                                }
18034                            }
18035                            break;
18036                        default:
18037                            // For everything else, assign next empty cached process
18038                            // level and bump that up.  Note that this means that
18039                            // long-running services that have dropped down to the
18040                            // cached level will be treated as empty (since their process
18041                            // state is still as a service), which is what we want.
18042                            app.curRawAdj = curEmptyAdj;
18043                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18044                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18045                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18046                                    + ")");
18047                            if (curEmptyAdj != nextEmptyAdj) {
18048                                stepEmpty++;
18049                                if (stepEmpty >= emptyFactor) {
18050                                    stepEmpty = 0;
18051                                    curEmptyAdj = nextEmptyAdj;
18052                                    nextEmptyAdj += 2;
18053                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18054                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18055                                    }
18056                                }
18057                            }
18058                            break;
18059                    }
18060                }
18061
18062                applyOomAdjLocked(app, TOP_APP, true, now);
18063
18064                // Count the number of process types.
18065                switch (app.curProcState) {
18066                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18067                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18068                        mNumCachedHiddenProcs++;
18069                        numCached++;
18070                        if (numCached > cachedProcessLimit) {
18071                            app.kill("cached #" + numCached, true);
18072                        }
18073                        break;
18074                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18075                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18076                                && app.lastActivityTime < oldTime) {
18077                            app.kill("empty for "
18078                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18079                                    / 1000) + "s", true);
18080                        } else {
18081                            numEmpty++;
18082                            if (numEmpty > emptyProcessLimit) {
18083                                app.kill("empty #" + numEmpty, true);
18084                            }
18085                        }
18086                        break;
18087                    default:
18088                        mNumNonCachedProcs++;
18089                        break;
18090                }
18091
18092                if (app.isolated && app.services.size() <= 0) {
18093                    // If this is an isolated process, and there are no
18094                    // services running in it, then the process is no longer
18095                    // needed.  We agressively kill these because we can by
18096                    // definition not re-use the same process again, and it is
18097                    // good to avoid having whatever code was running in them
18098                    // left sitting around after no longer needed.
18099                    app.kill("isolated not needed", true);
18100                }
18101
18102                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18103                        && !app.killedByAm) {
18104                    numTrimming++;
18105                }
18106            }
18107        }
18108
18109        mNumServiceProcs = mNewNumServiceProcs;
18110
18111        // Now determine the memory trimming level of background processes.
18112        // Unfortunately we need to start at the back of the list to do this
18113        // properly.  We only do this if the number of background apps we
18114        // are managing to keep around is less than half the maximum we desire;
18115        // if we are keeping a good number around, we'll let them use whatever
18116        // memory they want.
18117        final int numCachedAndEmpty = numCached + numEmpty;
18118        int memFactor;
18119        if (numCached <= ProcessList.TRIM_CACHED_APPS
18120                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18121            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18122                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18123            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18124                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18125            } else {
18126                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18127            }
18128        } else {
18129            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18130        }
18131        // We always allow the memory level to go up (better).  We only allow it to go
18132        // down if we are in a state where that is allowed, *and* the total number of processes
18133        // has gone down since last time.
18134        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18135                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18136                + " last=" + mLastNumProcesses);
18137        if (memFactor > mLastMemoryLevel) {
18138            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18139                memFactor = mLastMemoryLevel;
18140                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18141            }
18142        }
18143        mLastMemoryLevel = memFactor;
18144        mLastNumProcesses = mLruProcesses.size();
18145        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18146        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18147        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18148            if (mLowRamStartTime == 0) {
18149                mLowRamStartTime = now;
18150            }
18151            int step = 0;
18152            int fgTrimLevel;
18153            switch (memFactor) {
18154                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18155                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18156                    break;
18157                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18158                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18159                    break;
18160                default:
18161                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18162                    break;
18163            }
18164            int factor = numTrimming/3;
18165            int minFactor = 2;
18166            if (mHomeProcess != null) minFactor++;
18167            if (mPreviousProcess != null) minFactor++;
18168            if (factor < minFactor) factor = minFactor;
18169            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18170            for (int i=N-1; i>=0; i--) {
18171                ProcessRecord app = mLruProcesses.get(i);
18172                if (allChanged || app.procStateChanged) {
18173                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18174                    app.procStateChanged = false;
18175                }
18176                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18177                        && !app.killedByAm) {
18178                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18179                        try {
18180                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18181                                    "Trimming memory of " + app.processName
18182                                    + " to " + curLevel);
18183                            app.thread.scheduleTrimMemory(curLevel);
18184                        } catch (RemoteException e) {
18185                        }
18186                        if (false) {
18187                            // For now we won't do this; our memory trimming seems
18188                            // to be good enough at this point that destroying
18189                            // activities causes more harm than good.
18190                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18191                                    && app != mHomeProcess && app != mPreviousProcess) {
18192                                // Need to do this on its own message because the stack may not
18193                                // be in a consistent state at this point.
18194                                // For these apps we will also finish their activities
18195                                // to help them free memory.
18196                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18197                            }
18198                        }
18199                    }
18200                    app.trimMemoryLevel = curLevel;
18201                    step++;
18202                    if (step >= factor) {
18203                        step = 0;
18204                        switch (curLevel) {
18205                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18206                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18207                                break;
18208                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18209                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18210                                break;
18211                        }
18212                    }
18213                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18214                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18215                            && app.thread != null) {
18216                        try {
18217                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18218                                    "Trimming memory of heavy-weight " + app.processName
18219                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18220                            app.thread.scheduleTrimMemory(
18221                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18222                        } catch (RemoteException e) {
18223                        }
18224                    }
18225                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18226                } else {
18227                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18228                            || app.systemNoUi) && app.pendingUiClean) {
18229                        // If this application is now in the background and it
18230                        // had done UI, then give it the special trim level to
18231                        // have it free UI resources.
18232                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18233                        if (app.trimMemoryLevel < level && app.thread != null) {
18234                            try {
18235                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18236                                        "Trimming memory of bg-ui " + app.processName
18237                                        + " to " + level);
18238                                app.thread.scheduleTrimMemory(level);
18239                            } catch (RemoteException e) {
18240                            }
18241                        }
18242                        app.pendingUiClean = false;
18243                    }
18244                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18245                        try {
18246                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18247                                    "Trimming memory of fg " + app.processName
18248                                    + " to " + fgTrimLevel);
18249                            app.thread.scheduleTrimMemory(fgTrimLevel);
18250                        } catch (RemoteException e) {
18251                        }
18252                    }
18253                    app.trimMemoryLevel = fgTrimLevel;
18254                }
18255            }
18256        } else {
18257            if (mLowRamStartTime != 0) {
18258                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18259                mLowRamStartTime = 0;
18260            }
18261            for (int i=N-1; i>=0; i--) {
18262                ProcessRecord app = mLruProcesses.get(i);
18263                if (allChanged || app.procStateChanged) {
18264                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18265                    app.procStateChanged = false;
18266                }
18267                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18268                        || app.systemNoUi) && app.pendingUiClean) {
18269                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18270                            && app.thread != null) {
18271                        try {
18272                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18273                                    "Trimming memory of ui hidden " + app.processName
18274                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18275                            app.thread.scheduleTrimMemory(
18276                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18277                        } catch (RemoteException e) {
18278                        }
18279                    }
18280                    app.pendingUiClean = false;
18281                }
18282                app.trimMemoryLevel = 0;
18283            }
18284        }
18285
18286        if (mAlwaysFinishActivities) {
18287            // Need to do this on its own message because the stack may not
18288            // be in a consistent state at this point.
18289            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18290        }
18291
18292        if (allChanged) {
18293            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18294        }
18295
18296        if (mProcessStats.shouldWriteNowLocked(now)) {
18297            mHandler.post(new Runnable() {
18298                @Override public void run() {
18299                    synchronized (ActivityManagerService.this) {
18300                        mProcessStats.writeStateAsyncLocked();
18301                    }
18302                }
18303            });
18304        }
18305
18306        if (DEBUG_OOM_ADJ) {
18307            if (false) {
18308                RuntimeException here = new RuntimeException("here");
18309                here.fillInStackTrace();
18310                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18311            } else {
18312                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18313            }
18314        }
18315    }
18316
18317    final void trimApplications() {
18318        synchronized (this) {
18319            int i;
18320
18321            // First remove any unused application processes whose package
18322            // has been removed.
18323            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18324                final ProcessRecord app = mRemovedProcesses.get(i);
18325                if (app.activities.size() == 0
18326                        && app.curReceiver == null && app.services.size() == 0) {
18327                    Slog.i(
18328                        TAG, "Exiting empty application process "
18329                        + app.processName + " ("
18330                        + (app.thread != null ? app.thread.asBinder() : null)
18331                        + ")\n");
18332                    if (app.pid > 0 && app.pid != MY_PID) {
18333                        app.kill("empty", false);
18334                    } else {
18335                        try {
18336                            app.thread.scheduleExit();
18337                        } catch (Exception e) {
18338                            // Ignore exceptions.
18339                        }
18340                    }
18341                    cleanUpApplicationRecordLocked(app, false, true, -1);
18342                    mRemovedProcesses.remove(i);
18343
18344                    if (app.persistent) {
18345                        addAppLocked(app.info, false, null /* ABI override */);
18346                    }
18347                }
18348            }
18349
18350            // Now update the oom adj for all processes.
18351            updateOomAdjLocked();
18352        }
18353    }
18354
18355    /** This method sends the specified signal to each of the persistent apps */
18356    public void signalPersistentProcesses(int sig) throws RemoteException {
18357        if (sig != Process.SIGNAL_USR1) {
18358            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18359        }
18360
18361        synchronized (this) {
18362            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18363                    != PackageManager.PERMISSION_GRANTED) {
18364                throw new SecurityException("Requires permission "
18365                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18366            }
18367
18368            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18369                ProcessRecord r = mLruProcesses.get(i);
18370                if (r.thread != null && r.persistent) {
18371                    Process.sendSignal(r.pid, sig);
18372                }
18373            }
18374        }
18375    }
18376
18377    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18378        if (proc == null || proc == mProfileProc) {
18379            proc = mProfileProc;
18380            profileType = mProfileType;
18381            clearProfilerLocked();
18382        }
18383        if (proc == null) {
18384            return;
18385        }
18386        try {
18387            proc.thread.profilerControl(false, null, profileType);
18388        } catch (RemoteException e) {
18389            throw new IllegalStateException("Process disappeared");
18390        }
18391    }
18392
18393    private void clearProfilerLocked() {
18394        if (mProfileFd != null) {
18395            try {
18396                mProfileFd.close();
18397            } catch (IOException e) {
18398            }
18399        }
18400        mProfileApp = null;
18401        mProfileProc = null;
18402        mProfileFile = null;
18403        mProfileType = 0;
18404        mAutoStopProfiler = false;
18405        mSamplingInterval = 0;
18406    }
18407
18408    public boolean profileControl(String process, int userId, boolean start,
18409            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18410
18411        try {
18412            synchronized (this) {
18413                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18414                // its own permission.
18415                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18416                        != PackageManager.PERMISSION_GRANTED) {
18417                    throw new SecurityException("Requires permission "
18418                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18419                }
18420
18421                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18422                    throw new IllegalArgumentException("null profile info or fd");
18423                }
18424
18425                ProcessRecord proc = null;
18426                if (process != null) {
18427                    proc = findProcessLocked(process, userId, "profileControl");
18428                }
18429
18430                if (start && (proc == null || proc.thread == null)) {
18431                    throw new IllegalArgumentException("Unknown process: " + process);
18432                }
18433
18434                if (start) {
18435                    stopProfilerLocked(null, 0);
18436                    setProfileApp(proc.info, proc.processName, profilerInfo);
18437                    mProfileProc = proc;
18438                    mProfileType = profileType;
18439                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18440                    try {
18441                        fd = fd.dup();
18442                    } catch (IOException e) {
18443                        fd = null;
18444                    }
18445                    profilerInfo.profileFd = fd;
18446                    proc.thread.profilerControl(start, profilerInfo, profileType);
18447                    fd = null;
18448                    mProfileFd = null;
18449                } else {
18450                    stopProfilerLocked(proc, profileType);
18451                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18452                        try {
18453                            profilerInfo.profileFd.close();
18454                        } catch (IOException e) {
18455                        }
18456                    }
18457                }
18458
18459                return true;
18460            }
18461        } catch (RemoteException e) {
18462            throw new IllegalStateException("Process disappeared");
18463        } finally {
18464            if (profilerInfo != null && profilerInfo.profileFd != null) {
18465                try {
18466                    profilerInfo.profileFd.close();
18467                } catch (IOException e) {
18468                }
18469            }
18470        }
18471    }
18472
18473    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18474        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18475                userId, true, ALLOW_FULL_ONLY, callName, null);
18476        ProcessRecord proc = null;
18477        try {
18478            int pid = Integer.parseInt(process);
18479            synchronized (mPidsSelfLocked) {
18480                proc = mPidsSelfLocked.get(pid);
18481            }
18482        } catch (NumberFormatException e) {
18483        }
18484
18485        if (proc == null) {
18486            ArrayMap<String, SparseArray<ProcessRecord>> all
18487                    = mProcessNames.getMap();
18488            SparseArray<ProcessRecord> procs = all.get(process);
18489            if (procs != null && procs.size() > 0) {
18490                proc = procs.valueAt(0);
18491                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18492                    for (int i=1; i<procs.size(); i++) {
18493                        ProcessRecord thisProc = procs.valueAt(i);
18494                        if (thisProc.userId == userId) {
18495                            proc = thisProc;
18496                            break;
18497                        }
18498                    }
18499                }
18500            }
18501        }
18502
18503        return proc;
18504    }
18505
18506    public boolean dumpHeap(String process, int userId, boolean managed,
18507            String path, ParcelFileDescriptor fd) throws RemoteException {
18508
18509        try {
18510            synchronized (this) {
18511                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18512                // its own permission (same as profileControl).
18513                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18514                        != PackageManager.PERMISSION_GRANTED) {
18515                    throw new SecurityException("Requires permission "
18516                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18517                }
18518
18519                if (fd == null) {
18520                    throw new IllegalArgumentException("null fd");
18521                }
18522
18523                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18524                if (proc == null || proc.thread == null) {
18525                    throw new IllegalArgumentException("Unknown process: " + process);
18526                }
18527
18528                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18529                if (!isDebuggable) {
18530                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18531                        throw new SecurityException("Process not debuggable: " + proc);
18532                    }
18533                }
18534
18535                proc.thread.dumpHeap(managed, path, fd);
18536                fd = null;
18537                return true;
18538            }
18539        } catch (RemoteException e) {
18540            throw new IllegalStateException("Process disappeared");
18541        } finally {
18542            if (fd != null) {
18543                try {
18544                    fd.close();
18545                } catch (IOException e) {
18546                }
18547            }
18548        }
18549    }
18550
18551    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18552    public void monitor() {
18553        synchronized (this) { }
18554    }
18555
18556    void onCoreSettingsChange(Bundle settings) {
18557        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18558            ProcessRecord processRecord = mLruProcesses.get(i);
18559            try {
18560                if (processRecord.thread != null) {
18561                    processRecord.thread.setCoreSettings(settings);
18562                }
18563            } catch (RemoteException re) {
18564                /* ignore */
18565            }
18566        }
18567    }
18568
18569    // Multi-user methods
18570
18571    /**
18572     * Start user, if its not already running, but don't bring it to foreground.
18573     */
18574    @Override
18575    public boolean startUserInBackground(final int userId) {
18576        return startUser(userId, /* foreground */ false);
18577    }
18578
18579    /**
18580     * Start user, if its not already running, and bring it to foreground.
18581     */
18582    boolean startUserInForeground(final int userId, Dialog dlg) {
18583        boolean result = startUser(userId, /* foreground */ true);
18584        dlg.dismiss();
18585        return result;
18586    }
18587
18588    /**
18589     * Refreshes the list of users related to the current user when either a
18590     * user switch happens or when a new related user is started in the
18591     * background.
18592     */
18593    private void updateCurrentProfileIdsLocked() {
18594        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18595                mCurrentUserId, false /* enabledOnly */);
18596        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18597        for (int i = 0; i < currentProfileIds.length; i++) {
18598            currentProfileIds[i] = profiles.get(i).id;
18599        }
18600        mCurrentProfileIds = currentProfileIds;
18601
18602        synchronized (mUserProfileGroupIdsSelfLocked) {
18603            mUserProfileGroupIdsSelfLocked.clear();
18604            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18605            for (int i = 0; i < users.size(); i++) {
18606                UserInfo user = users.get(i);
18607                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18608                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18609                }
18610            }
18611        }
18612    }
18613
18614    private Set getProfileIdsLocked(int userId) {
18615        Set userIds = new HashSet<Integer>();
18616        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18617                userId, false /* enabledOnly */);
18618        for (UserInfo user : profiles) {
18619            userIds.add(Integer.valueOf(user.id));
18620        }
18621        return userIds;
18622    }
18623
18624    @Override
18625    public boolean switchUser(final int userId) {
18626        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18627        String userName;
18628        synchronized (this) {
18629            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18630            if (userInfo == null) {
18631                Slog.w(TAG, "No user info for user #" + userId);
18632                return false;
18633            }
18634            if (userInfo.isManagedProfile()) {
18635                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18636                return false;
18637            }
18638            userName = userInfo.name;
18639            mTargetUserId = userId;
18640        }
18641        mHandler.removeMessages(START_USER_SWITCH_MSG);
18642        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18643        return true;
18644    }
18645
18646    private void showUserSwitchDialog(int userId, String userName) {
18647        // The dialog will show and then initiate the user switch by calling startUserInForeground
18648        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18649                true /* above system */);
18650        d.show();
18651    }
18652
18653    private boolean startUser(final int userId, final boolean foreground) {
18654        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18655                != PackageManager.PERMISSION_GRANTED) {
18656            String msg = "Permission Denial: switchUser() from pid="
18657                    + Binder.getCallingPid()
18658                    + ", uid=" + Binder.getCallingUid()
18659                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18660            Slog.w(TAG, msg);
18661            throw new SecurityException(msg);
18662        }
18663
18664        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18665
18666        final long ident = Binder.clearCallingIdentity();
18667        try {
18668            synchronized (this) {
18669                final int oldUserId = mCurrentUserId;
18670                if (oldUserId == userId) {
18671                    return true;
18672                }
18673
18674                mStackSupervisor.setLockTaskModeLocked(null, false);
18675
18676                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18677                if (userInfo == null) {
18678                    Slog.w(TAG, "No user info for user #" + userId);
18679                    return false;
18680                }
18681                if (foreground && userInfo.isManagedProfile()) {
18682                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18683                    return false;
18684                }
18685
18686                if (foreground) {
18687                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18688                            R.anim.screen_user_enter);
18689                }
18690
18691                boolean needStart = false;
18692
18693                // If the user we are switching to is not currently started, then
18694                // we need to start it now.
18695                if (mStartedUsers.get(userId) == null) {
18696                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18697                    updateStartedUserArrayLocked();
18698                    needStart = true;
18699                }
18700
18701                final Integer userIdInt = Integer.valueOf(userId);
18702                mUserLru.remove(userIdInt);
18703                mUserLru.add(userIdInt);
18704
18705                if (foreground) {
18706                    mCurrentUserId = userId;
18707                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18708                    updateCurrentProfileIdsLocked();
18709                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18710                    // Once the internal notion of the active user has switched, we lock the device
18711                    // with the option to show the user switcher on the keyguard.
18712                    mWindowManager.lockNow(null);
18713                } else {
18714                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18715                    updateCurrentProfileIdsLocked();
18716                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18717                    mUserLru.remove(currentUserIdInt);
18718                    mUserLru.add(currentUserIdInt);
18719                }
18720
18721                final UserStartedState uss = mStartedUsers.get(userId);
18722
18723                // Make sure user is in the started state.  If it is currently
18724                // stopping, we need to knock that off.
18725                if (uss.mState == UserStartedState.STATE_STOPPING) {
18726                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18727                    // so we can just fairly silently bring the user back from
18728                    // the almost-dead.
18729                    uss.mState = UserStartedState.STATE_RUNNING;
18730                    updateStartedUserArrayLocked();
18731                    needStart = true;
18732                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18733                    // This means ACTION_SHUTDOWN has been sent, so we will
18734                    // need to treat this as a new boot of the user.
18735                    uss.mState = UserStartedState.STATE_BOOTING;
18736                    updateStartedUserArrayLocked();
18737                    needStart = true;
18738                }
18739
18740                if (uss.mState == UserStartedState.STATE_BOOTING) {
18741                    // Booting up a new user, need to tell system services about it.
18742                    // Note that this is on the same handler as scheduling of broadcasts,
18743                    // which is important because it needs to go first.
18744                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18745                }
18746
18747                if (foreground) {
18748                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18749                            oldUserId));
18750                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18751                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18752                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18753                            oldUserId, userId, uss));
18754                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18755                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18756                }
18757
18758                if (needStart) {
18759                    // Send USER_STARTED broadcast
18760                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18761                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18762                            | Intent.FLAG_RECEIVER_FOREGROUND);
18763                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18764                    broadcastIntentLocked(null, null, intent,
18765                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18766                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18767                }
18768
18769                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18770                    if (userId != UserHandle.USER_OWNER) {
18771                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18772                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18773                        broadcastIntentLocked(null, null, intent, null,
18774                                new IIntentReceiver.Stub() {
18775                                    public void performReceive(Intent intent, int resultCode,
18776                                            String data, Bundle extras, boolean ordered,
18777                                            boolean sticky, int sendingUser) {
18778                                        onUserInitialized(uss, foreground, oldUserId, userId);
18779                                    }
18780                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18781                                true, false, MY_PID, Process.SYSTEM_UID,
18782                                userId);
18783                        uss.initializing = true;
18784                    } else {
18785                        getUserManagerLocked().makeInitialized(userInfo.id);
18786                    }
18787                }
18788
18789                if (foreground) {
18790                    if (!uss.initializing) {
18791                        moveUserToForeground(uss, oldUserId, userId);
18792                    }
18793                } else {
18794                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18795                }
18796
18797                if (needStart) {
18798                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18799                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18800                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18801                    broadcastIntentLocked(null, null, intent,
18802                            null, new IIntentReceiver.Stub() {
18803                                @Override
18804                                public void performReceive(Intent intent, int resultCode, String data,
18805                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18806                                        throws RemoteException {
18807                                }
18808                            }, 0, null, null,
18809                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18810                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18811                }
18812            }
18813        } finally {
18814            Binder.restoreCallingIdentity(ident);
18815        }
18816
18817        return true;
18818    }
18819
18820    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18821        long ident = Binder.clearCallingIdentity();
18822        try {
18823            Intent intent;
18824            if (oldUserId >= 0) {
18825                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18826                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18827                int count = profiles.size();
18828                for (int i = 0; i < count; i++) {
18829                    int profileUserId = profiles.get(i).id;
18830                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18831                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18832                            | Intent.FLAG_RECEIVER_FOREGROUND);
18833                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18834                    broadcastIntentLocked(null, null, intent,
18835                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18836                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18837                }
18838            }
18839            if (newUserId >= 0) {
18840                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18841                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18842                int count = profiles.size();
18843                for (int i = 0; i < count; i++) {
18844                    int profileUserId = profiles.get(i).id;
18845                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18846                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18847                            | Intent.FLAG_RECEIVER_FOREGROUND);
18848                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18849                    broadcastIntentLocked(null, null, intent,
18850                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18851                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18852                }
18853                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18854                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18855                        | Intent.FLAG_RECEIVER_FOREGROUND);
18856                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18857                broadcastIntentLocked(null, null, intent,
18858                        null, null, 0, null, null,
18859                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18860                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18861            }
18862        } finally {
18863            Binder.restoreCallingIdentity(ident);
18864        }
18865    }
18866
18867    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18868            final int newUserId) {
18869        final int N = mUserSwitchObservers.beginBroadcast();
18870        if (N > 0) {
18871            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18872                int mCount = 0;
18873                @Override
18874                public void sendResult(Bundle data) throws RemoteException {
18875                    synchronized (ActivityManagerService.this) {
18876                        if (mCurUserSwitchCallback == this) {
18877                            mCount++;
18878                            if (mCount == N) {
18879                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18880                            }
18881                        }
18882                    }
18883                }
18884            };
18885            synchronized (this) {
18886                uss.switching = true;
18887                mCurUserSwitchCallback = callback;
18888            }
18889            for (int i=0; i<N; i++) {
18890                try {
18891                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18892                            newUserId, callback);
18893                } catch (RemoteException e) {
18894                }
18895            }
18896        } else {
18897            synchronized (this) {
18898                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18899            }
18900        }
18901        mUserSwitchObservers.finishBroadcast();
18902    }
18903
18904    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18905        synchronized (this) {
18906            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18907            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18908        }
18909    }
18910
18911    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18912        mCurUserSwitchCallback = null;
18913        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18914        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18915                oldUserId, newUserId, uss));
18916    }
18917
18918    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18919        synchronized (this) {
18920            if (foreground) {
18921                moveUserToForeground(uss, oldUserId, newUserId);
18922            }
18923        }
18924
18925        completeSwitchAndInitalize(uss, newUserId, true, false);
18926    }
18927
18928    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18929        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18930        if (homeInFront) {
18931            startHomeActivityLocked(newUserId);
18932        } else {
18933            mStackSupervisor.resumeTopActivitiesLocked();
18934        }
18935        EventLogTags.writeAmSwitchUser(newUserId);
18936        getUserManagerLocked().userForeground(newUserId);
18937        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18938    }
18939
18940    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18941        completeSwitchAndInitalize(uss, newUserId, false, true);
18942    }
18943
18944    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18945            boolean clearInitializing, boolean clearSwitching) {
18946        boolean unfrozen = false;
18947        synchronized (this) {
18948            if (clearInitializing) {
18949                uss.initializing = false;
18950                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18951            }
18952            if (clearSwitching) {
18953                uss.switching = false;
18954            }
18955            if (!uss.switching && !uss.initializing) {
18956                mWindowManager.stopFreezingScreen();
18957                unfrozen = true;
18958            }
18959        }
18960        if (unfrozen) {
18961            final int N = mUserSwitchObservers.beginBroadcast();
18962            for (int i=0; i<N; i++) {
18963                try {
18964                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18965                } catch (RemoteException e) {
18966                }
18967            }
18968            mUserSwitchObservers.finishBroadcast();
18969        }
18970    }
18971
18972    void scheduleStartProfilesLocked() {
18973        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18974            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18975                    DateUtils.SECOND_IN_MILLIS);
18976        }
18977    }
18978
18979    void startProfilesLocked() {
18980        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18981        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18982                mCurrentUserId, false /* enabledOnly */);
18983        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18984        for (UserInfo user : profiles) {
18985            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18986                    && user.id != mCurrentUserId) {
18987                toStart.add(user);
18988            }
18989        }
18990        final int n = toStart.size();
18991        int i = 0;
18992        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18993            startUserInBackground(toStart.get(i).id);
18994        }
18995        if (i < n) {
18996            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18997        }
18998    }
18999
19000    void finishUserBoot(UserStartedState uss) {
19001        synchronized (this) {
19002            if (uss.mState == UserStartedState.STATE_BOOTING
19003                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19004                uss.mState = UserStartedState.STATE_RUNNING;
19005                final int userId = uss.mHandle.getIdentifier();
19006                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19007                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19008                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19009                broadcastIntentLocked(null, null, intent,
19010                        null, null, 0, null, null,
19011                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19012                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19013            }
19014        }
19015    }
19016
19017    void finishUserSwitch(UserStartedState uss) {
19018        synchronized (this) {
19019            finishUserBoot(uss);
19020
19021            startProfilesLocked();
19022
19023            int num = mUserLru.size();
19024            int i = 0;
19025            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19026                Integer oldUserId = mUserLru.get(i);
19027                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19028                if (oldUss == null) {
19029                    // Shouldn't happen, but be sane if it does.
19030                    mUserLru.remove(i);
19031                    num--;
19032                    continue;
19033                }
19034                if (oldUss.mState == UserStartedState.STATE_STOPPING
19035                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19036                    // This user is already stopping, doesn't count.
19037                    num--;
19038                    i++;
19039                    continue;
19040                }
19041                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19042                    // Owner and current can't be stopped, but count as running.
19043                    i++;
19044                    continue;
19045                }
19046                // This is a user to be stopped.
19047                stopUserLocked(oldUserId, null);
19048                num--;
19049                i++;
19050            }
19051        }
19052    }
19053
19054    @Override
19055    public int stopUser(final int userId, final IStopUserCallback callback) {
19056        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19057                != PackageManager.PERMISSION_GRANTED) {
19058            String msg = "Permission Denial: switchUser() from pid="
19059                    + Binder.getCallingPid()
19060                    + ", uid=" + Binder.getCallingUid()
19061                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19062            Slog.w(TAG, msg);
19063            throw new SecurityException(msg);
19064        }
19065        if (userId <= 0) {
19066            throw new IllegalArgumentException("Can't stop primary user " + userId);
19067        }
19068        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19069        synchronized (this) {
19070            return stopUserLocked(userId, callback);
19071        }
19072    }
19073
19074    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19075        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19076        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19077            return ActivityManager.USER_OP_IS_CURRENT;
19078        }
19079
19080        final UserStartedState uss = mStartedUsers.get(userId);
19081        if (uss == null) {
19082            // User is not started, nothing to do...  but we do need to
19083            // callback if requested.
19084            if (callback != null) {
19085                mHandler.post(new Runnable() {
19086                    @Override
19087                    public void run() {
19088                        try {
19089                            callback.userStopped(userId);
19090                        } catch (RemoteException e) {
19091                        }
19092                    }
19093                });
19094            }
19095            return ActivityManager.USER_OP_SUCCESS;
19096        }
19097
19098        if (callback != null) {
19099            uss.mStopCallbacks.add(callback);
19100        }
19101
19102        if (uss.mState != UserStartedState.STATE_STOPPING
19103                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19104            uss.mState = UserStartedState.STATE_STOPPING;
19105            updateStartedUserArrayLocked();
19106
19107            long ident = Binder.clearCallingIdentity();
19108            try {
19109                // We are going to broadcast ACTION_USER_STOPPING and then
19110                // once that is done send a final ACTION_SHUTDOWN and then
19111                // stop the user.
19112                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19113                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19114                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19115                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19116                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19117                // This is the result receiver for the final shutdown broadcast.
19118                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19119                    @Override
19120                    public void performReceive(Intent intent, int resultCode, String data,
19121                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19122                        finishUserStop(uss);
19123                    }
19124                };
19125                // This is the result receiver for the initial stopping broadcast.
19126                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19127                    @Override
19128                    public void performReceive(Intent intent, int resultCode, String data,
19129                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19130                        // On to the next.
19131                        synchronized (ActivityManagerService.this) {
19132                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19133                                // Whoops, we are being started back up.  Abort, abort!
19134                                return;
19135                            }
19136                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19137                        }
19138                        mBatteryStatsService.noteEvent(
19139                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19140                                Integer.toString(userId), userId);
19141                        mSystemServiceManager.stopUser(userId);
19142                        broadcastIntentLocked(null, null, shutdownIntent,
19143                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19144                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19145                    }
19146                };
19147                // Kick things off.
19148                broadcastIntentLocked(null, null, stoppingIntent,
19149                        null, stoppingReceiver, 0, null, null,
19150                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19151                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19152            } finally {
19153                Binder.restoreCallingIdentity(ident);
19154            }
19155        }
19156
19157        return ActivityManager.USER_OP_SUCCESS;
19158    }
19159
19160    void finishUserStop(UserStartedState uss) {
19161        final int userId = uss.mHandle.getIdentifier();
19162        boolean stopped;
19163        ArrayList<IStopUserCallback> callbacks;
19164        synchronized (this) {
19165            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19166            if (mStartedUsers.get(userId) != uss) {
19167                stopped = false;
19168            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19169                stopped = false;
19170            } else {
19171                stopped = true;
19172                // User can no longer run.
19173                mStartedUsers.remove(userId);
19174                mUserLru.remove(Integer.valueOf(userId));
19175                updateStartedUserArrayLocked();
19176
19177                // Clean up all state and processes associated with the user.
19178                // Kill all the processes for the user.
19179                forceStopUserLocked(userId, "finish user");
19180            }
19181
19182            // Explicitly remove the old information in mRecentTasks.
19183            removeRecentTasksForUserLocked(userId);
19184        }
19185
19186        for (int i=0; i<callbacks.size(); i++) {
19187            try {
19188                if (stopped) callbacks.get(i).userStopped(userId);
19189                else callbacks.get(i).userStopAborted(userId);
19190            } catch (RemoteException e) {
19191            }
19192        }
19193
19194        if (stopped) {
19195            mSystemServiceManager.cleanupUser(userId);
19196            synchronized (this) {
19197                mStackSupervisor.removeUserLocked(userId);
19198            }
19199        }
19200    }
19201
19202    @Override
19203    public UserInfo getCurrentUser() {
19204        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19205                != PackageManager.PERMISSION_GRANTED) && (
19206                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19207                != PackageManager.PERMISSION_GRANTED)) {
19208            String msg = "Permission Denial: getCurrentUser() from pid="
19209                    + Binder.getCallingPid()
19210                    + ", uid=" + Binder.getCallingUid()
19211                    + " requires " + INTERACT_ACROSS_USERS;
19212            Slog.w(TAG, msg);
19213            throw new SecurityException(msg);
19214        }
19215        synchronized (this) {
19216            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19217            return getUserManagerLocked().getUserInfo(userId);
19218        }
19219    }
19220
19221    int getCurrentUserIdLocked() {
19222        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19223    }
19224
19225    @Override
19226    public boolean isUserRunning(int userId, boolean orStopped) {
19227        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19228                != PackageManager.PERMISSION_GRANTED) {
19229            String msg = "Permission Denial: isUserRunning() from pid="
19230                    + Binder.getCallingPid()
19231                    + ", uid=" + Binder.getCallingUid()
19232                    + " requires " + INTERACT_ACROSS_USERS;
19233            Slog.w(TAG, msg);
19234            throw new SecurityException(msg);
19235        }
19236        synchronized (this) {
19237            return isUserRunningLocked(userId, orStopped);
19238        }
19239    }
19240
19241    boolean isUserRunningLocked(int userId, boolean orStopped) {
19242        UserStartedState state = mStartedUsers.get(userId);
19243        if (state == null) {
19244            return false;
19245        }
19246        if (orStopped) {
19247            return true;
19248        }
19249        return state.mState != UserStartedState.STATE_STOPPING
19250                && state.mState != UserStartedState.STATE_SHUTDOWN;
19251    }
19252
19253    @Override
19254    public int[] getRunningUserIds() {
19255        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19256                != PackageManager.PERMISSION_GRANTED) {
19257            String msg = "Permission Denial: isUserRunning() from pid="
19258                    + Binder.getCallingPid()
19259                    + ", uid=" + Binder.getCallingUid()
19260                    + " requires " + INTERACT_ACROSS_USERS;
19261            Slog.w(TAG, msg);
19262            throw new SecurityException(msg);
19263        }
19264        synchronized (this) {
19265            return mStartedUserArray;
19266        }
19267    }
19268
19269    private void updateStartedUserArrayLocked() {
19270        int num = 0;
19271        for (int i=0; i<mStartedUsers.size();  i++) {
19272            UserStartedState uss = mStartedUsers.valueAt(i);
19273            // This list does not include stopping users.
19274            if (uss.mState != UserStartedState.STATE_STOPPING
19275                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19276                num++;
19277            }
19278        }
19279        mStartedUserArray = new int[num];
19280        num = 0;
19281        for (int i=0; i<mStartedUsers.size();  i++) {
19282            UserStartedState uss = mStartedUsers.valueAt(i);
19283            if (uss.mState != UserStartedState.STATE_STOPPING
19284                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19285                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19286                num++;
19287            }
19288        }
19289    }
19290
19291    @Override
19292    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19293        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19294                != PackageManager.PERMISSION_GRANTED) {
19295            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19296                    + Binder.getCallingPid()
19297                    + ", uid=" + Binder.getCallingUid()
19298                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19299            Slog.w(TAG, msg);
19300            throw new SecurityException(msg);
19301        }
19302
19303        mUserSwitchObservers.register(observer);
19304    }
19305
19306    @Override
19307    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19308        mUserSwitchObservers.unregister(observer);
19309    }
19310
19311    private boolean userExists(int userId) {
19312        if (userId == 0) {
19313            return true;
19314        }
19315        UserManagerService ums = getUserManagerLocked();
19316        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19317    }
19318
19319    int[] getUsersLocked() {
19320        UserManagerService ums = getUserManagerLocked();
19321        return ums != null ? ums.getUserIds() : new int[] { 0 };
19322    }
19323
19324    UserManagerService getUserManagerLocked() {
19325        if (mUserManager == null) {
19326            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19327            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19328        }
19329        return mUserManager;
19330    }
19331
19332    private int applyUserId(int uid, int userId) {
19333        return UserHandle.getUid(userId, uid);
19334    }
19335
19336    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19337        if (info == null) return null;
19338        ApplicationInfo newInfo = new ApplicationInfo(info);
19339        newInfo.uid = applyUserId(info.uid, userId);
19340        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19341                + info.packageName;
19342        return newInfo;
19343    }
19344
19345    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19346        if (aInfo == null
19347                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19348            return aInfo;
19349        }
19350
19351        ActivityInfo info = new ActivityInfo(aInfo);
19352        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19353        return info;
19354    }
19355
19356    private final class LocalService extends ActivityManagerInternal {
19357        @Override
19358        public void onWakefulnessChanged(int wakefulness) {
19359            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19360        }
19361
19362        @Override
19363        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19364                String processName, String abiOverride, int uid, Runnable crashHandler) {
19365            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19366                    processName, abiOverride, uid, crashHandler);
19367        }
19368    }
19369
19370    /**
19371     * An implementation of IAppTask, that allows an app to manage its own tasks via
19372     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19373     * only the process that calls getAppTasks() can call the AppTask methods.
19374     */
19375    class AppTaskImpl extends IAppTask.Stub {
19376        private int mTaskId;
19377        private int mCallingUid;
19378
19379        public AppTaskImpl(int taskId, int callingUid) {
19380            mTaskId = taskId;
19381            mCallingUid = callingUid;
19382        }
19383
19384        private void checkCaller() {
19385            if (mCallingUid != Binder.getCallingUid()) {
19386                throw new SecurityException("Caller " + mCallingUid
19387                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19388            }
19389        }
19390
19391        @Override
19392        public void finishAndRemoveTask() {
19393            checkCaller();
19394
19395            synchronized (ActivityManagerService.this) {
19396                long origId = Binder.clearCallingIdentity();
19397                try {
19398                    if (!removeTaskByIdLocked(mTaskId, false)) {
19399                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19400                    }
19401                } finally {
19402                    Binder.restoreCallingIdentity(origId);
19403                }
19404            }
19405        }
19406
19407        @Override
19408        public ActivityManager.RecentTaskInfo getTaskInfo() {
19409            checkCaller();
19410
19411            synchronized (ActivityManagerService.this) {
19412                long origId = Binder.clearCallingIdentity();
19413                try {
19414                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19415                    if (tr == null) {
19416                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19417                    }
19418                    return createRecentTaskInfoFromTaskRecord(tr);
19419                } finally {
19420                    Binder.restoreCallingIdentity(origId);
19421                }
19422            }
19423        }
19424
19425        @Override
19426        public void moveToFront() {
19427            checkCaller();
19428
19429            final TaskRecord tr;
19430            synchronized (ActivityManagerService.this) {
19431                tr = recentTaskForIdLocked(mTaskId);
19432                if (tr == null) {
19433                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19434                }
19435                if (tr.getRootActivity() != null) {
19436                    moveTaskToFrontLocked(tr.taskId, 0, null);
19437                    return;
19438                }
19439            }
19440
19441            startActivityFromRecentsInner(tr.taskId, null);
19442        }
19443
19444        @Override
19445        public int startActivity(IBinder whoThread, String callingPackage,
19446                Intent intent, String resolvedType, Bundle options) {
19447            checkCaller();
19448
19449            int callingUser = UserHandle.getCallingUserId();
19450            TaskRecord tr;
19451            IApplicationThread appThread;
19452            synchronized (ActivityManagerService.this) {
19453                tr = recentTaskForIdLocked(mTaskId);
19454                if (tr == null) {
19455                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19456                }
19457                appThread = ApplicationThreadNative.asInterface(whoThread);
19458                if (appThread == null) {
19459                    throw new IllegalArgumentException("Bad app thread " + appThread);
19460                }
19461            }
19462            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19463                    resolvedType, null, null, null, null, 0, 0, null, null,
19464                    null, options, callingUser, null, tr);
19465        }
19466
19467        @Override
19468        public void setExcludeFromRecents(boolean exclude) {
19469            checkCaller();
19470
19471            synchronized (ActivityManagerService.this) {
19472                long origId = Binder.clearCallingIdentity();
19473                try {
19474                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19475                    if (tr == null) {
19476                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19477                    }
19478                    Intent intent = tr.getBaseIntent();
19479                    if (exclude) {
19480                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19481                    } else {
19482                        intent.setFlags(intent.getFlags()
19483                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19484                    }
19485                } finally {
19486                    Binder.restoreCallingIdentity(origId);
19487                }
19488            }
19489        }
19490    }
19491}
19492